omnius 1.0.535 → 1.0.537
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 +817 -163
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/prompts/agentic/system-medium.md +1 -1
- package/prompts/agentic/system-small.md +6 -5
package/dist/index.js
CHANGED
|
@@ -6981,7 +6981,7 @@ var init_file_write = __esm({
|
|
|
6981
6981
|
init_text_encoding();
|
|
6982
6982
|
FileWriteTool = class {
|
|
6983
6983
|
name = "file_write";
|
|
6984
|
-
description = "Create new files or deliberately replace small, empty, or placeholder files; use file_edit/file_patch for local changes. For content with heavy quoting, raw JSON, control characters, or large full-file payloads, pass content_base64 instead of shell heredocs/cat/tee.";
|
|
6984
|
+
description = "Create new files or deliberately replace small, empty, or placeholder files; use file_edit/file_patch for local changes. Existing-file replacement requires overwrite=true plus expected_hash from a fresh file_read; never use this as a fallback after a failed targeted edit. For content with heavy quoting, raw JSON, control characters, or large full-file payloads, pass content_base64 instead of shell heredocs/cat/tee.";
|
|
6985
6985
|
parameters = {
|
|
6986
6986
|
type: "object",
|
|
6987
6987
|
properties: {
|
|
@@ -296557,8 +296557,8 @@ var init_cron_agent = __esm({
|
|
|
296557
296557
|
}
|
|
296558
296558
|
const lines = [];
|
|
296559
296559
|
const formatJob = (job, scopeLabel, isThisProject) => {
|
|
296560
|
-
const
|
|
296561
|
-
lines.push(` ${
|
|
296560
|
+
const statusIcon2 = job.status === "active" ? "●" : job.status === "completed" ? "✔" : job.status === "paused" ? "⏸" : "✖";
|
|
296561
|
+
lines.push(` ${statusIcon2} [${job.id}] ${job.status.toUpperCase()} [${scopeLabel}]`);
|
|
296562
296562
|
lines.push(` Goal: ${job.goal.slice(0, 80)}${job.goal.length > 80 ? "..." : ""}`);
|
|
296563
296563
|
lines.push(` Schedule: ${job.scheduleDescription}`);
|
|
296564
296564
|
lines.push(` Runs: ${job.runCount}${job.maxRuns > 0 ? `/${job.maxRuns}` : ""}`);
|
|
@@ -553281,6 +553281,7 @@ function spawnFullSubAgent(task, opts, onOutput, onComplete) {
|
|
|
553281
553281
|
child.stderr?.on("data", (chunk) => {
|
|
553282
553282
|
const text2 = chunk.toString();
|
|
553283
553283
|
outputBuffer.push(...text2.split("\n").filter((l2) => l2.length > 0));
|
|
553284
|
+
onOutput?.(text2);
|
|
553284
553285
|
});
|
|
553285
553286
|
child.on("exit", (code8) => {
|
|
553286
553287
|
clearInterval(heartbeatTimer);
|
|
@@ -567114,13 +567115,103 @@ function normalizeShellCommand(command) {
|
|
|
567114
567115
|
function splitConjunctiveVerifyCommand(command) {
|
|
567115
567116
|
return normalizeShellCommand(command).split(/\s+&&\s+/).map((part) => part.trim()).filter(Boolean);
|
|
567116
567117
|
}
|
|
567118
|
+
function stripVerifierFallbackSuffix(command) {
|
|
567119
|
+
let quote2 = null;
|
|
567120
|
+
for (let i2 = 0; i2 < command.length - 1; i2++) {
|
|
567121
|
+
const ch = command[i2];
|
|
567122
|
+
if (quote2) {
|
|
567123
|
+
if (ch === quote2 && command[i2 - 1] !== "\\")
|
|
567124
|
+
quote2 = null;
|
|
567125
|
+
continue;
|
|
567126
|
+
}
|
|
567127
|
+
if (ch === "'" || ch === '"') {
|
|
567128
|
+
quote2 = ch;
|
|
567129
|
+
continue;
|
|
567130
|
+
}
|
|
567131
|
+
if (ch === "|" && command[i2 + 1] === "|") {
|
|
567132
|
+
return command.slice(0, i2).trim();
|
|
567133
|
+
}
|
|
567134
|
+
}
|
|
567135
|
+
return command.trim();
|
|
567136
|
+
}
|
|
567137
|
+
function stageHeadProgram(stage2) {
|
|
567138
|
+
const tokens = stage2.trim().split(/\s+/);
|
|
567139
|
+
let i2 = 0;
|
|
567140
|
+
while (i2 < tokens.length) {
|
|
567141
|
+
const token = tokens[i2];
|
|
567142
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(token)) {
|
|
567143
|
+
i2++;
|
|
567144
|
+
continue;
|
|
567145
|
+
}
|
|
567146
|
+
const base3 = token.replace(/^["']|["']$/g, "").split("/").pop() ?? token;
|
|
567147
|
+
if (STAGE_PREFIX_PROGRAMS.has(base3)) {
|
|
567148
|
+
i2++;
|
|
567149
|
+
if (base3 === "timeout" && /^[0-9]+[smhd]?$/.test(tokens[i2] ?? ""))
|
|
567150
|
+
i2++;
|
|
567151
|
+
continue;
|
|
567152
|
+
}
|
|
567153
|
+
return base3.toLowerCase();
|
|
567154
|
+
}
|
|
567155
|
+
return null;
|
|
567156
|
+
}
|
|
567157
|
+
function commandIsPureReadOnlyPipeline(command) {
|
|
567158
|
+
const stages = [];
|
|
567159
|
+
let current = "";
|
|
567160
|
+
let quote2 = null;
|
|
567161
|
+
const raw = command.trim();
|
|
567162
|
+
if (!raw)
|
|
567163
|
+
return false;
|
|
567164
|
+
for (let i2 = 0; i2 < raw.length; i2++) {
|
|
567165
|
+
const ch = raw[i2];
|
|
567166
|
+
if (quote2) {
|
|
567167
|
+
current += ch;
|
|
567168
|
+
if (ch === quote2 && raw[i2 - 1] !== "\\")
|
|
567169
|
+
quote2 = null;
|
|
567170
|
+
continue;
|
|
567171
|
+
}
|
|
567172
|
+
if (ch === "'" || ch === '"') {
|
|
567173
|
+
quote2 = ch;
|
|
567174
|
+
current += ch;
|
|
567175
|
+
continue;
|
|
567176
|
+
}
|
|
567177
|
+
if (ch === "&" && raw[i2 + 1] === "&") {
|
|
567178
|
+
stages.push(current);
|
|
567179
|
+
current = "";
|
|
567180
|
+
i2++;
|
|
567181
|
+
continue;
|
|
567182
|
+
}
|
|
567183
|
+
if (ch === "|") {
|
|
567184
|
+
stages.push(current);
|
|
567185
|
+
current = "";
|
|
567186
|
+
if (raw[i2 + 1] === "|")
|
|
567187
|
+
i2++;
|
|
567188
|
+
continue;
|
|
567189
|
+
}
|
|
567190
|
+
if (ch === ";") {
|
|
567191
|
+
stages.push(current);
|
|
567192
|
+
current = "";
|
|
567193
|
+
continue;
|
|
567194
|
+
}
|
|
567195
|
+
if (ch === "$" && raw[i2 + 1] === "(")
|
|
567196
|
+
return false;
|
|
567197
|
+
if (ch === "`")
|
|
567198
|
+
return false;
|
|
567199
|
+
current += ch;
|
|
567200
|
+
}
|
|
567201
|
+
stages.push(current);
|
|
567202
|
+
const meaningful = stages.map((s2) => s2.trim()).filter(Boolean);
|
|
567203
|
+
if (meaningful.length === 0)
|
|
567204
|
+
return false;
|
|
567205
|
+
return meaningful.every((stage2) => {
|
|
567206
|
+
const head = stageHeadProgram(stage2);
|
|
567207
|
+
return head !== null && PURE_READER_PROGRAMS.has(head);
|
|
567208
|
+
});
|
|
567209
|
+
}
|
|
567117
567210
|
function commandReliablySatisfiesVerifyCommand(observedCommand, verifyCommand) {
|
|
567118
567211
|
const observed = normalizeShellCommand(observedCommand);
|
|
567119
|
-
const expected = normalizeShellCommand(verifyCommand);
|
|
567212
|
+
const expected = normalizeShellCommand(stripVerifierFallbackSuffix(verifyCommand));
|
|
567120
567213
|
if (!observed || !expected)
|
|
567121
567214
|
return false;
|
|
567122
|
-
if (expected.includes(" || "))
|
|
567123
|
-
return false;
|
|
567124
567215
|
if (observed === expected)
|
|
567125
567216
|
return true;
|
|
567126
567217
|
if (observed.startsWith(`${expected} && `) && !observed.includes(" || ")) {
|
|
@@ -567141,9 +567232,93 @@ function verifyCommandSatisfiedByShellHistory(verifyCommand, history) {
|
|
|
567141
567232
|
return false;
|
|
567142
567233
|
return parts.every((part) => successful.some((entry) => commandReliablySatisfiesVerifyCommand(entry.command, part)));
|
|
567143
567234
|
}
|
|
567235
|
+
var PURE_READER_PROGRAMS, STAGE_PREFIX_PROGRAMS;
|
|
567144
567236
|
var init_verificationCommand = __esm({
|
|
567145
567237
|
"packages/orchestrator/dist/verificationCommand.js"() {
|
|
567146
567238
|
"use strict";
|
|
567239
|
+
PURE_READER_PROGRAMS = /* @__PURE__ */ new Set([
|
|
567240
|
+
"cat",
|
|
567241
|
+
"tac",
|
|
567242
|
+
"tail",
|
|
567243
|
+
"head",
|
|
567244
|
+
"less",
|
|
567245
|
+
"more",
|
|
567246
|
+
"grep",
|
|
567247
|
+
"egrep",
|
|
567248
|
+
"fgrep",
|
|
567249
|
+
"rg",
|
|
567250
|
+
"ag",
|
|
567251
|
+
"awk",
|
|
567252
|
+
"gawk",
|
|
567253
|
+
"sed",
|
|
567254
|
+
"gsed",
|
|
567255
|
+
"sort",
|
|
567256
|
+
"uniq",
|
|
567257
|
+
"wc",
|
|
567258
|
+
"cut",
|
|
567259
|
+
"tr",
|
|
567260
|
+
"column",
|
|
567261
|
+
"echo",
|
|
567262
|
+
"printf",
|
|
567263
|
+
"ls",
|
|
567264
|
+
"dir",
|
|
567265
|
+
"find",
|
|
567266
|
+
"fd",
|
|
567267
|
+
"stat",
|
|
567268
|
+
"file",
|
|
567269
|
+
"strings",
|
|
567270
|
+
"hexdump",
|
|
567271
|
+
"xxd",
|
|
567272
|
+
"od",
|
|
567273
|
+
"jq",
|
|
567274
|
+
"yq",
|
|
567275
|
+
"tee",
|
|
567276
|
+
"dirname",
|
|
567277
|
+
"basename",
|
|
567278
|
+
"readlink",
|
|
567279
|
+
"realpath",
|
|
567280
|
+
"pwd",
|
|
567281
|
+
"date",
|
|
567282
|
+
"true",
|
|
567283
|
+
"false",
|
|
567284
|
+
"test",
|
|
567285
|
+
"type",
|
|
567286
|
+
"which",
|
|
567287
|
+
"whoami",
|
|
567288
|
+
"env",
|
|
567289
|
+
"printenv",
|
|
567290
|
+
"sleep",
|
|
567291
|
+
"cd",
|
|
567292
|
+
"diff",
|
|
567293
|
+
"cmp",
|
|
567294
|
+
"md5sum",
|
|
567295
|
+
"sha1sum",
|
|
567296
|
+
"sha256sum",
|
|
567297
|
+
"du",
|
|
567298
|
+
"df",
|
|
567299
|
+
"nl",
|
|
567300
|
+
"paste",
|
|
567301
|
+
"join",
|
|
567302
|
+
"comm",
|
|
567303
|
+
"expand",
|
|
567304
|
+
"unexpand",
|
|
567305
|
+
"fold",
|
|
567306
|
+
"rev",
|
|
567307
|
+
"seq",
|
|
567308
|
+
"xargs"
|
|
567309
|
+
]);
|
|
567310
|
+
STAGE_PREFIX_PROGRAMS = /* @__PURE__ */ new Set([
|
|
567311
|
+
"sudo",
|
|
567312
|
+
"command",
|
|
567313
|
+
"builtin",
|
|
567314
|
+
"nice",
|
|
567315
|
+
"ionice",
|
|
567316
|
+
"time",
|
|
567317
|
+
"timeout",
|
|
567318
|
+
"nohup",
|
|
567319
|
+
"stdbuf",
|
|
567320
|
+
"unbuffer"
|
|
567321
|
+
]);
|
|
567147
567322
|
}
|
|
567148
567323
|
});
|
|
567149
567324
|
|
|
@@ -586374,6 +586549,8 @@ var init_agenticRunner = __esm({
|
|
|
586374
586549
|
_completionCaveat = null;
|
|
586375
586550
|
_completionLedger = null;
|
|
586376
586551
|
_staleEditFamilies = /* @__PURE__ */ new Map();
|
|
586552
|
+
/** Semantic retry counter for blocked full-file writes (payload-independent). */
|
|
586553
|
+
_blockedFullWriteAttempts = /* @__PURE__ */ new Map();
|
|
586377
586554
|
_lastReadTurnByPathKey = /* @__PURE__ */ new Map();
|
|
586378
586555
|
_recentSuccessfulReplacements = [];
|
|
586379
586556
|
// ── WO-AM-01/04/10: Associative memory stores ──
|
|
@@ -589283,8 +589460,9 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589283
589460
|
return this._declaredVerifierCommand;
|
|
589284
589461
|
}
|
|
589285
589462
|
const diagnostics = parseCompilerDiagnostics(output);
|
|
589286
|
-
if (diagnostics.length > 0 &&
|
|
589287
|
-
|
|
589463
|
+
if (diagnostics.length > 0 && !commandIsPureReadOnlyPipeline(trimmed)) {
|
|
589464
|
+
const latched = stripVerifierFallbackSuffix(trimmed);
|
|
589465
|
+
return latched || trimmed;
|
|
589288
589466
|
}
|
|
589289
589467
|
return null;
|
|
589290
589468
|
}
|
|
@@ -589294,19 +589472,68 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589294
589472
|
return false;
|
|
589295
589473
|
return commandReliablySatisfiesVerifyCommand(command.trim(), state.verifierCommand);
|
|
589296
589474
|
}
|
|
589475
|
+
/**
|
|
589476
|
+
* When a tool result was triaged for size (full payload saved to
|
|
589477
|
+
* `.omnius/tool-results/<hash>.txt`), append the saved payload so
|
|
589478
|
+
* diagnostics parsing sees the complete output. Without this, a large
|
|
589479
|
+
* failed build's `file:line:col: error:` lines can be cut out of the
|
|
589480
|
+
* triage envelope and the run never registers as a verifier run.
|
|
589481
|
+
* Best effort and bounded — never throws into the loop.
|
|
589482
|
+
*/
|
|
589483
|
+
_expandTriagedPayloadForDiagnostics(text2) {
|
|
589484
|
+
if (!text2 || !text2.includes(TRIAGE_SAVED_PATH_MARKER))
|
|
589485
|
+
return text2;
|
|
589486
|
+
const MAX_PAYLOAD_BYTES = 1e6;
|
|
589487
|
+
const MAX_FILES2 = 2;
|
|
589488
|
+
const extras = [];
|
|
589489
|
+
let searchFrom = 0;
|
|
589490
|
+
for (let i2 = 0; i2 < MAX_FILES2; i2++) {
|
|
589491
|
+
const markerAt = text2.indexOf(TRIAGE_SAVED_PATH_MARKER, searchFrom);
|
|
589492
|
+
if (markerAt === -1)
|
|
589493
|
+
break;
|
|
589494
|
+
const pathStart = markerAt + TRIAGE_SAVED_PATH_MARKER.length;
|
|
589495
|
+
const restOfLine = text2.slice(pathStart, text2.indexOf("\n", pathStart) === -1 ? void 0 : text2.indexOf("\n", pathStart));
|
|
589496
|
+
searchFrom = pathStart;
|
|
589497
|
+
const endIdx = (() => {
|
|
589498
|
+
const emDash = restOfLine.indexOf(" — ");
|
|
589499
|
+
if (emDash !== -1)
|
|
589500
|
+
return emDash;
|
|
589501
|
+
const bracket = restOfLine.indexOf("]");
|
|
589502
|
+
return bracket !== -1 ? bracket : restOfLine.length;
|
|
589503
|
+
})();
|
|
589504
|
+
const savedPath = restOfLine.slice(0, endIdx).trim();
|
|
589505
|
+
if (!savedPath)
|
|
589506
|
+
continue;
|
|
589507
|
+
try {
|
|
589508
|
+
if (!_fsExistsSync(savedPath))
|
|
589509
|
+
continue;
|
|
589510
|
+
const stat9 = _fsStatSync(savedPath);
|
|
589511
|
+
if (!stat9.isFile())
|
|
589512
|
+
continue;
|
|
589513
|
+
const raw = _fsReadFileSync(savedPath, "utf8");
|
|
589514
|
+
extras.push(raw.length > MAX_PAYLOAD_BYTES ? raw.slice(0, MAX_PAYLOAD_BYTES) : raw);
|
|
589515
|
+
} catch {
|
|
589516
|
+
}
|
|
589517
|
+
}
|
|
589518
|
+
if (extras.length === 0)
|
|
589519
|
+
return text2;
|
|
589520
|
+
return `${text2}
|
|
589521
|
+
${extras.join("\n")}`;
|
|
589522
|
+
}
|
|
589297
589523
|
_observeCompileVerifierResult(input) {
|
|
589298
589524
|
const diagnostics = rankCompilerDiagnostics(parseCompilerDiagnostics(input.output));
|
|
589525
|
+
const verifierCommand = stripVerifierFallbackSuffix(input.verifierCommand) || input.verifierCommand.trim();
|
|
589299
589526
|
const previousDiagnostics = this._lastDeclaredVerifierDiagnostics;
|
|
589300
|
-
this._declaredVerifierCommand =
|
|
589527
|
+
this._declaredVerifierCommand = verifierCommand;
|
|
589301
589528
|
this._lastDeclaredVerifierOutput = input.output;
|
|
589302
589529
|
this._lastDeclaredVerifierDiagnostics = diagnostics;
|
|
589303
589530
|
if (!this._compileFixLoop && diagnostics.length === 0)
|
|
589304
589531
|
return null;
|
|
589305
|
-
const verifierFingerprint = compileFixVerifierFingerprint(
|
|
589532
|
+
const verifierFingerprint = compileFixVerifierFingerprint(verifierCommand);
|
|
589306
589533
|
const existingCards = this._compileFixLoop?.cards ?? [];
|
|
589307
589534
|
const cards = diagnostics.length > 0 ? buildCompileFixCards({
|
|
589308
589535
|
diagnostics,
|
|
589309
|
-
verifierCommand
|
|
589536
|
+
verifierCommand,
|
|
589310
589537
|
turn: input.turn,
|
|
589311
589538
|
existingCards
|
|
589312
589539
|
}) : existingCards;
|
|
@@ -589315,22 +589542,25 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589315
589542
|
existingCards,
|
|
589316
589543
|
observedCards: cards,
|
|
589317
589544
|
diagnostics,
|
|
589318
|
-
verifierCommand
|
|
589545
|
+
verifierCommand,
|
|
589319
589546
|
turn: input.turn,
|
|
589320
589547
|
verifierPassed: input.success && diagnostics.length === 0
|
|
589321
589548
|
});
|
|
589322
589549
|
this._compileFixLoop = {
|
|
589323
589550
|
active: diagnostics.length > 0 || nextCards.some((card) => card.status !== "verified"),
|
|
589324
|
-
verifierCommand
|
|
589551
|
+
verifierCommand,
|
|
589325
589552
|
verifierFingerprint,
|
|
589326
589553
|
verifierDirtySinceTurn: null,
|
|
589327
589554
|
lastVerifierRunTurn: input.turn,
|
|
589328
589555
|
lastVerifierPassedTurn: input.success && diagnostics.length === 0 ? input.turn : null,
|
|
589329
589556
|
lastMutationTurn: this._compileFixLoop?.lastMutationTurn ?? null,
|
|
589330
|
-
cards: nextCards
|
|
589557
|
+
cards: nextCards,
|
|
589558
|
+
// A live verifier run resolves the gate's demand — the block streak
|
|
589559
|
+
// is over regardless of pass/fail.
|
|
589560
|
+
preflightBlockStreak: 0
|
|
589331
589561
|
};
|
|
589332
589562
|
this._mirrorCompileFixCardsToWorkboard(nextCards, {
|
|
589333
|
-
command:
|
|
589563
|
+
command: verifierCommand,
|
|
589334
589564
|
success: input.success && diagnostics.length === 0,
|
|
589335
589565
|
turn: input.turn,
|
|
589336
589566
|
beforeDiagnosticCount: previousDiagnostics.length,
|
|
@@ -589342,7 +589572,7 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589342
589572
|
if (input.success && diagnostics.length === 0) {
|
|
589343
589573
|
this.emit({
|
|
589344
589574
|
type: "status",
|
|
589345
|
-
content: `compile_error_fix_loop: verifier passed (${
|
|
589575
|
+
content: `compile_error_fix_loop: verifier passed (${verifierCommand}); compile cards verified`,
|
|
589346
589576
|
turn: input.turn,
|
|
589347
589577
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
589348
589578
|
});
|
|
@@ -589361,7 +589591,7 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589361
589591
|
}
|
|
589362
589592
|
this.emit({
|
|
589363
589593
|
type: "status",
|
|
589364
|
-
content: `compile_error_fix_loop_started: verifierCommand=${
|
|
589594
|
+
content: `compile_error_fix_loop_started: verifierCommand=${verifierCommand}; cardId=${top.id}; diagnosticFingerprint=${top.diagnostic.fingerprint}; afterDiagnosticCount=${diagnostics.length}`,
|
|
589365
589595
|
turn: input.turn,
|
|
589366
589596
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
589367
589597
|
});
|
|
@@ -589561,14 +589791,7 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589561
589791
|
if (!state?.active)
|
|
589562
589792
|
return;
|
|
589563
589793
|
const normalized = paths.map((p2) => this._normalizeEvidencePath(p2)).filter(Boolean);
|
|
589564
|
-
const
|
|
589565
|
-
const todos = this.readSessionTodos() || [];
|
|
589566
|
-
const artifacts = todos.flatMap((todo) => Array.isArray(todo.declaredArtifacts) ? todo.declaredArtifacts.filter((p2) => typeof p2 === "string") : []);
|
|
589567
|
-
const relevant = normalized.length === 0 || normalized.some((pathValue) => {
|
|
589568
|
-
if (pathValue.startsWith(".omnius/"))
|
|
589569
|
-
return false;
|
|
589570
|
-
return owned.some((ownedPath) => this._pathsOverlapForVerifier(pathValue, ownedPath)) || artifacts.some((artifactPath) => this._pathsOverlapForVerifier(pathValue, artifactPath)) || /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|c|cc|cpp|cxx|h|hpp|hh|hxx|ino)$/i.test(pathValue);
|
|
589571
|
-
});
|
|
589794
|
+
const relevant = normalized.length === 0 || this._compileFixPathsTouchProjectSources(normalized, state);
|
|
589572
589795
|
if (!relevant)
|
|
589573
589796
|
return;
|
|
589574
589797
|
state.verifierDirtySinceTurn = turn;
|
|
@@ -589595,6 +589818,24 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589595
589818
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
589596
589819
|
});
|
|
589597
589820
|
}
|
|
589821
|
+
/**
|
|
589822
|
+
* True when any of the given normalized paths touches project source:
|
|
589823
|
+
* files owned by compile-fix cards, declared todo artifacts, or files
|
|
589824
|
+
* with a source-code extension. Build side effects (logs, artifacts,
|
|
589825
|
+
* `.omnius/` bookkeeping) do not count.
|
|
589826
|
+
*/
|
|
589827
|
+
_compileFixPathsTouchProjectSources(normalizedPaths, state) {
|
|
589828
|
+
const owned = state.cards.flatMap((card) => card.ownedFiles);
|
|
589829
|
+
const todos = this.readSessionTodos() || [];
|
|
589830
|
+
const artifacts = todos.flatMap((todo) => Array.isArray(todo.declaredArtifacts) ? todo.declaredArtifacts.filter((p2) => typeof p2 === "string") : []);
|
|
589831
|
+
return normalizedPaths.some((pathValue) => {
|
|
589832
|
+
if (pathValue.startsWith(".omnius/"))
|
|
589833
|
+
return false;
|
|
589834
|
+
return owned.some((ownedPath) => this._pathsOverlapForVerifier(pathValue, ownedPath)) || artifacts.some((artifactPath) => this._pathsOverlapForVerifier(pathValue, artifactPath)) || /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|c|cc|cpp|cxx|h|hpp|hh|hxx|ino)$/i.test(pathValue);
|
|
589835
|
+
});
|
|
589836
|
+
}
|
|
589837
|
+
/** Consecutive preflight blocks before the gate yields instead of blocking. */
|
|
589838
|
+
static COMPILE_FIX_GATE_YIELD_AFTER = 3;
|
|
589598
589839
|
_compileFixLoopPreflightBlock(toolName, args, turn, shellLikelyMutatesFilesystem) {
|
|
589599
589840
|
const state = this._compileFixLoop;
|
|
589600
589841
|
if (!state?.active)
|
|
@@ -589605,29 +589846,62 @@ Pick the SMALLEST concrete deliverable from the spec — typically the project e
|
|
|
589605
589846
|
if (toolName === "shell") {
|
|
589606
589847
|
const command = String(args["command"] ?? args["cmd"] ?? "").trim();
|
|
589607
589848
|
if (commandReliablySatisfiesVerifyCommand(command, state.verifierCommand)) {
|
|
589849
|
+
state.preflightBlockStreak = 0;
|
|
589608
589850
|
return null;
|
|
589609
589851
|
}
|
|
589610
589852
|
if (!shellLikelyMutatesFilesystem)
|
|
589611
589853
|
return null;
|
|
589854
|
+
const extraction = extractShellMutationPaths(command, {
|
|
589855
|
+
workingDir: this.authoritativeWorkingDirectory()
|
|
589856
|
+
});
|
|
589857
|
+
const mutationPaths = extraction.paths.map((p2) => this._normalizeEvidencePath(p2)).filter(Boolean);
|
|
589858
|
+
if (mutationPaths.length === 0 || !this._compileFixPathsTouchProjectSources(mutationPaths, state)) {
|
|
589859
|
+
return null;
|
|
589860
|
+
}
|
|
589612
589861
|
} else if (!this._isProjectEditTool(toolName)) {
|
|
589613
589862
|
return null;
|
|
589614
589863
|
}
|
|
589864
|
+
const yieldAfter = _AgenticRunner.COMPILE_FIX_GATE_YIELD_AFTER;
|
|
589865
|
+
const streak = (state.preflightBlockStreak ?? 0) + 1;
|
|
589866
|
+
if (streak > yieldAfter) {
|
|
589867
|
+
state.preflightBlockStreak = 0;
|
|
589868
|
+
this.emit({
|
|
589869
|
+
type: "status",
|
|
589870
|
+
content: `compile_error_verifier_dirty: gate yielded to ${toolName} after ${yieldAfter} consecutive blocks at turn ${turn}`,
|
|
589871
|
+
turn,
|
|
589872
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
589873
|
+
});
|
|
589874
|
+
return {
|
|
589875
|
+
kind: "yield",
|
|
589876
|
+
notice: [
|
|
589877
|
+
`[COMPILE FIX GATE YIELDED — verifier still required]`,
|
|
589878
|
+
`The verifier-required gate blocked ${yieldAfter} consecutive tool calls and is yielding so work can continue.`,
|
|
589879
|
+
`Verifier evidence is still stale. Run the verifier as your next evidence step:`,
|
|
589880
|
+
` ${state.verifierCommand}`,
|
|
589881
|
+
`Any real build/test command whose output shows current compiler diagnostics is also accepted as the live verifier.`,
|
|
589882
|
+
`task_complete remains blocked until a verifier run passes after the last mutation.`
|
|
589883
|
+
].join("\n")
|
|
589884
|
+
};
|
|
589885
|
+
}
|
|
589886
|
+
state.preflightBlockStreak = streak;
|
|
589615
589887
|
const message2 = [
|
|
589616
589888
|
`[COMPILE ERROR FIX LOOP BLOCKED — declared verifier required]`,
|
|
589617
589889
|
`A compile-fix card was patched, so the next mutation/evidence step must be the live verifier.`,
|
|
589618
|
-
`
|
|
589890
|
+
`Run this now: ${state.verifierCommand}`,
|
|
589891
|
+
`Any real build/test command whose output shows current compiler diagnostics is also accepted.`,
|
|
589619
589892
|
`dirtySinceTurn: ${state.verifierDirtySinceTurn}`,
|
|
589620
589893
|
`lastMutationTurn: ${state.lastMutationTurn}`,
|
|
589621
589894
|
`lastVerifierRunTurn: ${state.lastVerifierRunTurn}`,
|
|
589622
|
-
`blockedTool: ${toolName}
|
|
589895
|
+
`blockedTool: ${toolName}`,
|
|
589896
|
+
`consecutiveBlocks: ${streak}/${yieldAfter} (gate yields after ${yieldAfter})`
|
|
589623
589897
|
].join("\n");
|
|
589624
589898
|
this.emit({
|
|
589625
589899
|
type: "status",
|
|
589626
|
-
content: `compile_error_verifier_dirty: blocked ${toolName} at turn ${turn}`,
|
|
589900
|
+
content: `compile_error_verifier_dirty: blocked ${toolName} at turn ${turn} (${streak}/${yieldAfter})`,
|
|
589627
589901
|
turn,
|
|
589628
589902
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
589629
589903
|
});
|
|
589630
|
-
return message2;
|
|
589904
|
+
return { kind: "block", message: message2 };
|
|
589631
589905
|
}
|
|
589632
589906
|
_compileFixLoopCompletionBlocker(turn) {
|
|
589633
589907
|
const state = this._compileFixLoop;
|
|
@@ -589985,6 +590259,8 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
589985
590259
|
if (!command.trim())
|
|
589986
590260
|
return false;
|
|
589987
590261
|
void result;
|
|
590262
|
+
if (commandIsPureReadOnlyPipeline(command))
|
|
590263
|
+
return false;
|
|
589988
590264
|
return /\b(test|tests|vitest|jest|pytest|go test|cargo test|npm test|pnpm test|yarn test|typecheck|tsc|build|verify|verification|check)\b/i.test(command);
|
|
589989
590265
|
}
|
|
589990
590266
|
_shouldSuppressCompletionDiscoveryEvidence(toolName, result, targetPaths) {
|
|
@@ -594502,6 +594778,7 @@ Respond with your assessment, then take action.`;
|
|
|
594502
594778
|
this._lastDeclaredVerifierOutput = null;
|
|
594503
594779
|
this._lastDeclaredVerifierDiagnostics = [];
|
|
594504
594780
|
this._staleEditFamilies.clear();
|
|
594781
|
+
this._blockedFullWriteAttempts.clear();
|
|
594505
594782
|
this._lastReadTurnByPathKey.clear();
|
|
594506
594783
|
this._recentSuccessfulReplacements = [];
|
|
594507
594784
|
this._lastWorldStateTurn = -1;
|
|
@@ -595882,7 +596159,7 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
595882
596159
|
PICK: <number 1-3>
|
|
595883
596160
|
WHY: <one sentence>
|
|
595884
596161
|
FALSIFICATION: <observable signal that would refute the pick>
|
|
595885
|
-
NEXT ACTION: <a single
|
|
596162
|
+
NEXT ACTION: <a single targeted edit — file_edit / file_patch / batch_edit; file_write only for a verified-new file>`;
|
|
595886
596163
|
messages2.push({ role: "system", content: _replan60 });
|
|
595887
596164
|
stagnationCooldownUntilTurn = turn + REG60_COOLDOWN_TURNS;
|
|
595888
596165
|
const _tel60 = this._describeTopClusterTelemetry();
|
|
@@ -596143,7 +596420,7 @@ If this matches your current shape, try it before continuing.`
|
|
|
596143
596420
|
] : [
|
|
596144
596421
|
`Pick ONE of these for your next response:`,
|
|
596145
596422
|
``,
|
|
596146
|
-
` (a) PRODUCE: emit a
|
|
596423
|
+
` (a) PRODUCE: emit a targeted file_edit / file_patch / batch_edit that creates or changes project content. Use file_write only after verifying the target is new/placeholder and never as recovery for a blocked existing-file write. Use shell only for commands/tests/system operations, not as a workaround for failed edit-tool encoding.`,
|
|
596147
596424
|
``,
|
|
596148
596425
|
` (b) ERROR-INFORMED LOCAL TRIAGE: anchor on the freshest local failure, identify the implicated file/path/symbol/command, then make one targeted local move instead of broad exploration.`,
|
|
596149
596426
|
``,
|
|
@@ -597859,7 +598136,7 @@ Corrective action: try a different approach first: read relevant files, adjust a
|
|
|
597859
598136
|
`A REG-61 FIRST-EDIT NUDGE was issued earlier and has not yet been satisfied. The directive asks you to prioritize a creative edit. You issued '${tc.name}' instead, which is a read/explore/shell call.`,
|
|
597860
598137
|
``,
|
|
597861
598138
|
`This call was ALLOWED through (needed context should never be blocked), but try to make a creative edit next:`,
|
|
597862
|
-
` • file_write — create a new file`,
|
|
598139
|
+
` • file_write — create a verified-new file only (never use it to repair an existing target)`,
|
|
597863
598140
|
` • file_edit — modify an existing file (find/replace)`,
|
|
597864
598141
|
` • batch_edit — multiple find/replace edits in one call`,
|
|
597865
598142
|
` • file_patch — apply a version-checked line-range patch`,
|
|
@@ -598024,7 +598301,7 @@ Read the current file if needed, make a different concrete edit, or move to veri
|
|
|
598024
598301
|
systemGuidance: staleBlockOutput
|
|
598025
598302
|
};
|
|
598026
598303
|
}
|
|
598027
|
-
const staleRewriteBlock = this.staleEditOverwritePreflightBlock(tc.name, tc.arguments ?? {});
|
|
598304
|
+
const staleRewriteBlock = this.staleEditOverwritePreflightBlock(tc.name, tc.arguments ?? {}, turn);
|
|
598028
598305
|
if (staleRewriteBlock) {
|
|
598029
598306
|
const focusDecision2 = this._focusSupervisor?.evaluateProposedCall({
|
|
598030
598307
|
turn,
|
|
@@ -598420,8 +598697,10 @@ ${cachedResult}`,
|
|
|
598420
598697
|
};
|
|
598421
598698
|
}
|
|
598422
598699
|
}
|
|
598423
|
-
const
|
|
598424
|
-
if (
|
|
598700
|
+
const compileLoopPreflight = !repeatShortCircuit ? this._compileFixLoopPreflightBlock(tc.name, tc.arguments ?? {}, turn, shellLikelyMutatesFilesystem) : null;
|
|
598701
|
+
if (compileLoopPreflight?.kind === "yield") {
|
|
598702
|
+
pushSoftInjection("system", compileLoopPreflight.notice);
|
|
598703
|
+
} else if (compileLoopPreflight) {
|
|
598425
598704
|
this.emit({
|
|
598426
598705
|
type: "tool_call",
|
|
598427
598706
|
toolName: tc.name,
|
|
@@ -598433,7 +598712,7 @@ ${cachedResult}`,
|
|
|
598433
598712
|
type: "tool_result",
|
|
598434
598713
|
toolName: tc.name,
|
|
598435
598714
|
success: false,
|
|
598436
|
-
content:
|
|
598715
|
+
content: compileLoopPreflight.message.slice(0, 120),
|
|
598437
598716
|
turn,
|
|
598438
598717
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
598439
598718
|
});
|
|
@@ -598443,9 +598722,9 @@ ${cachedResult}`,
|
|
|
598443
598722
|
});
|
|
598444
598723
|
return {
|
|
598445
598724
|
tc,
|
|
598446
|
-
output:
|
|
598725
|
+
output: compileLoopPreflight.message,
|
|
598447
598726
|
success: false,
|
|
598448
|
-
systemGuidance:
|
|
598727
|
+
systemGuidance: compileLoopPreflight.message
|
|
598449
598728
|
};
|
|
598450
598729
|
}
|
|
598451
598730
|
this.emit({
|
|
@@ -600037,8 +600316,7 @@ ${structuralGuardGuidance}` : structuralGuardGuidance;
|
|
|
600037
600316
|
}
|
|
600038
600317
|
if (tc.name === "shell" && result.runtimeAuthored !== true) {
|
|
600039
600318
|
const shellCommand = String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "");
|
|
600040
|
-
const compileOutput =
|
|
600041
|
-
${result.error ?? ""}`;
|
|
600319
|
+
const compileOutput = this._expandTriagedPayloadForDiagnostics([result.output, result.llmContent, result.error].filter((part) => typeof part === "string" && part.length > 0).join("\n"));
|
|
600042
600320
|
const verifierCommand = this._declaredVerifierCommandForShell(shellCommand, compileOutput);
|
|
600043
600321
|
if (verifierCommand) {
|
|
600044
600322
|
const compileGuidance = this._observeCompileVerifierResult({
|
|
@@ -603032,6 +603310,29 @@ ${marker}` : marker);
|
|
|
603032
603310
|
const path16 = this.extractPrimaryToolPath(args);
|
|
603033
603311
|
if (!path16)
|
|
603034
603312
|
return null;
|
|
603313
|
+
const pathKey = this.staleEditPathKey(path16);
|
|
603314
|
+
const active = [...this._staleEditFamilies.values()].filter((entry) => entry.pathKey === pathKey).sort((a2, b) => b.lastFailureTurn - a2.lastFailureTurn).find((entry) => {
|
|
603315
|
+
const hasFreshRead = entry.lastReadTurn > entry.lastFailureTurn;
|
|
603316
|
+
const hasFreshMutation = entry.lastMutationTurn > entry.lastFailureTurn;
|
|
603317
|
+
return !hasFreshMutation && (entry.count >= 2 || !hasFreshRead);
|
|
603318
|
+
});
|
|
603319
|
+
if (active) {
|
|
603320
|
+
const tier = this.options.modelTier ?? "large";
|
|
603321
|
+
if (tier !== "small" && tier !== "medium")
|
|
603322
|
+
return null;
|
|
603323
|
+
return [
|
|
603324
|
+
`[EDIT REPAIR LOCK] A recent narrow edit to ${active.path} failed because the model-visible target diverged from disk (${active.errorKind}; latest_file_hash=${active.latestFileHash || "unknown"}).`,
|
|
603325
|
+
`This full-file overwrite was NOT executed. A stale narrow edit must not be repaired by broad file regeneration; preserve a constrained edit path until fresh target evidence is used.`,
|
|
603326
|
+
``,
|
|
603327
|
+
`Allowed next actions:`,
|
|
603328
|
+
`1. file_read ${active.path} once and construct file_edit from exact current text.`,
|
|
603329
|
+
`2. file_patch/file_edit against the latest file hash or a different target.`,
|
|
603330
|
+
`3. file_write with dry_run=true only to validate a full rewrite proposal without changing disk.`,
|
|
603331
|
+
`4. run verification if the desired change is already present, or report the explicit blocker instead of completing.`,
|
|
603332
|
+
``,
|
|
603333
|
+
`Stale target preview: ${active.preview}`
|
|
603334
|
+
].join("\n");
|
|
603335
|
+
}
|
|
603035
603336
|
let exists2 = false;
|
|
603036
603337
|
try {
|
|
603037
603338
|
const st = _fsStatSync(this._absoluteToolPath(path16), {
|
|
@@ -603043,6 +603344,15 @@ ${marker}` : marker);
|
|
|
603043
603344
|
}
|
|
603044
603345
|
if (!exists2)
|
|
603045
603346
|
return null;
|
|
603347
|
+
const overwrite = args["overwrite"] === true || args["overwriteExisting"] === true;
|
|
603348
|
+
if (!overwrite) {
|
|
603349
|
+
return [
|
|
603350
|
+
"[FULL FILE REWRITE CONTRACT]",
|
|
603351
|
+
`file_write would overwrite existing file ${path16}, but overwrite=true is missing.`,
|
|
603352
|
+
"This call was not executed. Prefer file_edit/file_patch for a local change.",
|
|
603353
|
+
"If a deliberate whole-file replacement is truly required, first file_read the current file and retry with overwrite=true and expected_hash equal to that read's sha256."
|
|
603354
|
+
].join("\n");
|
|
603355
|
+
}
|
|
603046
603356
|
if (!this._toolCallUsesFreshFileReadEvidence(toolName, args)) {
|
|
603047
603357
|
const fresh = this._freshReadHashForEditPath(path16);
|
|
603048
603358
|
return [
|
|
@@ -603156,16 +603466,13 @@ ${marker}` : marker);
|
|
|
603156
603466
|
}
|
|
603157
603467
|
return null;
|
|
603158
603468
|
}
|
|
603159
|
-
staleEditOverwritePreflightBlock(toolName, args) {
|
|
603469
|
+
staleEditOverwritePreflightBlock(toolName, args, turn = 0) {
|
|
603160
603470
|
if (toolName !== "file_write")
|
|
603161
603471
|
return null;
|
|
603162
603472
|
if (process.env["OMNIUS_ALLOW_STALE_REPAIR_OVERWRITE"] === "1")
|
|
603163
603473
|
return null;
|
|
603164
603474
|
if (args?.["dry_run"] === true || args?.["dryRun"] === true)
|
|
603165
603475
|
return null;
|
|
603166
|
-
const tier = this.options.modelTier ?? "large";
|
|
603167
|
-
if (tier !== "small" && tier !== "medium")
|
|
603168
|
-
return null;
|
|
603169
603476
|
const path16 = this.extractPrimaryToolPath(args);
|
|
603170
603477
|
if (!path16)
|
|
603171
603478
|
return null;
|
|
@@ -603175,19 +603482,49 @@ ${marker}` : marker);
|
|
|
603175
603482
|
const hasFreshMutation = entry.lastMutationTurn > entry.lastFailureTurn;
|
|
603176
603483
|
return !hasFreshMutation && (entry.count >= 2 || !hasFreshRead);
|
|
603177
603484
|
});
|
|
603178
|
-
if (
|
|
603485
|
+
if (active) {
|
|
603486
|
+
const tier = this.options.modelTier ?? "large";
|
|
603487
|
+
if (tier !== "small" && tier !== "medium")
|
|
603488
|
+
return null;
|
|
603489
|
+
return [
|
|
603490
|
+
`[EDIT REPAIR LOCK] A recent narrow edit to ${active.path} failed because the model-visible target diverged from disk (${active.errorKind}; latest_file_hash=${active.latestFileHash || "unknown"}).`,
|
|
603491
|
+
`This full-file overwrite was NOT executed. A stale narrow edit must not be repaired by broad file regeneration; preserve a constrained edit path until fresh target evidence is used.`,
|
|
603492
|
+
``,
|
|
603493
|
+
`Allowed next actions:`,
|
|
603494
|
+
`1. file_read ${active.path} once and construct file_edit from exact current text.`,
|
|
603495
|
+
`2. file_patch/file_edit against the latest file hash or a different target.`,
|
|
603496
|
+
`3. file_write with dry_run=true only to validate a full rewrite proposal without changing disk.`,
|
|
603497
|
+
`4. run verification if the desired change is already present, or report the explicit blocker instead of completing.`,
|
|
603498
|
+
``,
|
|
603499
|
+
`Stale target preview: ${active.preview}`
|
|
603500
|
+
].join("\n");
|
|
603501
|
+
}
|
|
603502
|
+
let exists2 = false;
|
|
603503
|
+
try {
|
|
603504
|
+
const st = _fsStatSync(this._absoluteToolPath(path16), {
|
|
603505
|
+
throwIfNoEntry: false
|
|
603506
|
+
});
|
|
603507
|
+
exists2 = !!st && st.isFile();
|
|
603508
|
+
} catch {
|
|
603509
|
+
exists2 = false;
|
|
603510
|
+
}
|
|
603511
|
+
if (!exists2)
|
|
603512
|
+
return null;
|
|
603513
|
+
const overwrite = args?.["overwrite"] === true || args?.["overwriteExisting"] === true;
|
|
603514
|
+
const hasFreshContract = overwrite && this._toolCallUsesFreshFileReadEvidence(toolName, args ?? {});
|
|
603515
|
+
if (hasFreshContract) {
|
|
603516
|
+
this._blockedFullWriteAttempts.delete(pathKey);
|
|
603517
|
+
return null;
|
|
603518
|
+
}
|
|
603519
|
+
const previous = this._blockedFullWriteAttempts.get(pathKey);
|
|
603520
|
+
const count = (previous?.count ?? 0) + 1;
|
|
603521
|
+
this._blockedFullWriteAttempts.set(pathKey, { count, lastTurn: turn });
|
|
603522
|
+
if (count < 2)
|
|
603179
603523
|
return null;
|
|
603180
603524
|
return [
|
|
603181
|
-
`[
|
|
603182
|
-
`This
|
|
603183
|
-
|
|
603184
|
-
`Allowed next actions:`,
|
|
603185
|
-
`1. file_read ${active.path} once and construct file_edit from exact current text.`,
|
|
603186
|
-
`2. file_patch/file_edit against the latest file hash or a different target.`,
|
|
603187
|
-
`3. file_write with dry_run=true only to validate a full rewrite proposal without changing disk.`,
|
|
603188
|
-
`4. run verification if the desired change is already present, or report the explicit blocker instead of completing.`,
|
|
603189
|
-
``,
|
|
603190
|
-
`Stale target preview: ${active.preview}`
|
|
603525
|
+
`[FULL FILE WRITE LOOP BLOCKED] ${path16} has already received ${count} blocked full-file write attempts.`,
|
|
603526
|
+
`This call was NOT executed, even if the replacement payload changed. Do not call file_write again for this path until a fresh file_read is completed.`,
|
|
603527
|
+
`Next action: use file_read ${path16}, then prefer file_patch/file_edit for the local change. Only an intentional whole-file replacement may use file_write with overwrite=true and expected_hash from that fresh read.`
|
|
603191
603528
|
].join("\n");
|
|
603192
603529
|
}
|
|
603193
603530
|
editReversalPreflightBlock(toolName, args, turn) {
|
|
@@ -603281,7 +603618,9 @@ ${marker}` : marker);
|
|
|
603281
603618
|
noteStaleEditGuardOutcome(toolName, args, result, turn) {
|
|
603282
603619
|
const path16 = this.extractPrimaryToolPath(args);
|
|
603283
603620
|
const pathKey = path16 ? this.staleEditPathKey(path16) : "";
|
|
603284
|
-
|
|
603621
|
+
const isFreshRead = toolName === "file_read" && path16 && result.success && result.runtimeAuthored !== true;
|
|
603622
|
+
if (isFreshRead) {
|
|
603623
|
+
this._blockedFullWriteAttempts.delete(pathKey);
|
|
603285
603624
|
for (const entry of this._staleEditFamilies.values()) {
|
|
603286
603625
|
if (entry.pathKey === pathKey)
|
|
603287
603626
|
entry.lastReadTurn = turn;
|
|
@@ -603289,6 +603628,7 @@ ${marker}` : marker);
|
|
|
603289
603628
|
return;
|
|
603290
603629
|
}
|
|
603291
603630
|
if (toolName === "file_write" && path16 && this._isRealProjectMutation(toolName, result)) {
|
|
603631
|
+
this._blockedFullWriteAttempts.delete(pathKey);
|
|
603292
603632
|
for (const [key2, entry] of this._staleEditFamilies) {
|
|
603293
603633
|
if (entry.pathKey === pathKey)
|
|
603294
603634
|
this._staleEditFamilies.delete(key2);
|
|
@@ -603302,6 +603642,7 @@ ${marker}` : marker);
|
|
|
603302
603642
|
return;
|
|
603303
603643
|
const targetPathKey = this.staleEditPathKey(target.path);
|
|
603304
603644
|
if (this._isRealProjectMutation(toolName, result) || result.alreadyApplied === true) {
|
|
603645
|
+
this._blockedFullWriteAttempts.delete(targetPathKey);
|
|
603305
603646
|
for (const [key2, entry] of this._staleEditFamilies) {
|
|
603306
603647
|
if (entry.pathKey === targetPathKey)
|
|
603307
603648
|
this._staleEditFamilies.delete(key2);
|
|
@@ -640617,6 +640958,50 @@ var init_dist9 = __esm({
|
|
|
640617
640958
|
});
|
|
640618
640959
|
|
|
640619
640960
|
// packages/cli/src/tui/stageIndicator.ts
|
|
640961
|
+
function stageForToolName(toolName) {
|
|
640962
|
+
const name10 = String(toolName ?? "").trim().toLowerCase();
|
|
640963
|
+
if (name10 === "file_read" || name10 === "structured_read") return "reading";
|
|
640964
|
+
if (name10 === "grep_search" || name10 === "glob_find" || name10 === "find_files" || name10 === "web_search" || name10 === "web_fetch" || name10 === "web_crawl")
|
|
640965
|
+
return "searching";
|
|
640966
|
+
if (name10 === "file_write" || name10 === "file_edit" || name10 === "file_patch" || name10 === "batch_edit" || name10 === "structured_file")
|
|
640967
|
+
return "writing";
|
|
640968
|
+
if (name10 === "shell" || name10 === "shell_async" || name10 === "run_tests" || name10 === "repl_exec")
|
|
640969
|
+
return "building";
|
|
640970
|
+
return "tool_call";
|
|
640971
|
+
}
|
|
640972
|
+
function stageForAgentEvent(event) {
|
|
640973
|
+
switch (event.type) {
|
|
640974
|
+
case "tool_call":
|
|
640975
|
+
return { stage: stageForToolName(event.toolName), detail: event.toolName };
|
|
640976
|
+
case "tool_result":
|
|
640977
|
+
return event.success === false ? {
|
|
640978
|
+
stage: "failed",
|
|
640979
|
+
detail: event.toolName ? `${event.toolName} failed` : void 0
|
|
640980
|
+
} : {
|
|
640981
|
+
stage: stageForToolName(event.toolName),
|
|
640982
|
+
detail: event.toolName
|
|
640983
|
+
};
|
|
640984
|
+
case "stream_start":
|
|
640985
|
+
case "assistant_text":
|
|
640986
|
+
case "model_response":
|
|
640987
|
+
return { stage: "planning" };
|
|
640988
|
+
case "compaction":
|
|
640989
|
+
return { stage: "compacting" };
|
|
640990
|
+
case "debug_adversary":
|
|
640991
|
+
return { stage: "adversary_audit" };
|
|
640992
|
+
case "complete":
|
|
640993
|
+
return { stage: "completed", detail: "done" };
|
|
640994
|
+
case "error":
|
|
640995
|
+
return {
|
|
640996
|
+
stage: "failed",
|
|
640997
|
+
detail: event.content?.trim().slice(0, 40) || void 0
|
|
640998
|
+
};
|
|
640999
|
+
case "user_interrupt":
|
|
641000
|
+
return { stage: "blocked", detail: "interrupted" };
|
|
641001
|
+
default:
|
|
641002
|
+
return null;
|
|
641003
|
+
}
|
|
641004
|
+
}
|
|
640620
641005
|
function tri360(x) {
|
|
640621
641006
|
const t2 = (x % 360 + 360) % 360;
|
|
640622
641007
|
return t2 < 180 ? t2 / 90 - 1 : 3 - t2 / 90;
|
|
@@ -640641,6 +641026,9 @@ function supportsTruecolor() {
|
|
|
640641
641026
|
function isSweepingStage(stage2) {
|
|
640642
641027
|
return SWEEPING_STAGES.has(stage2);
|
|
640643
641028
|
}
|
|
641029
|
+
function stageLabel2(stage2) {
|
|
641030
|
+
return STAGE_META[stage2].label;
|
|
641031
|
+
}
|
|
640644
641032
|
function stageBlockNeededWidth(stage2, detail) {
|
|
640645
641033
|
const meta = STAGE_META[stage2];
|
|
640646
641034
|
let body = meta.label;
|
|
@@ -640790,6 +641178,125 @@ var init_stageIndicator = __esm({
|
|
|
640790
641178
|
}
|
|
640791
641179
|
});
|
|
640792
641180
|
|
|
641181
|
+
// packages/cli/src/tui/sub-agent-live-block.ts
|
|
641182
|
+
function stageFallbackColor(stage2) {
|
|
641183
|
+
return STAGE_FALLBACK_COLOR[stage2];
|
|
641184
|
+
}
|
|
641185
|
+
function sanitizeSubAgentActivity(value2) {
|
|
641186
|
+
return value2.replace(ANSI_RE2, "").replace(/[\x00-\x1F\x7F]/g, " ").replace(/\s+/g, " ").trim().slice(0, MAX_ACTIVITY_CHARS);
|
|
641187
|
+
}
|
|
641188
|
+
function appendSubAgentActivity(entry, value2, maxLines = 3) {
|
|
641189
|
+
const line = sanitizeSubAgentActivity(value2);
|
|
641190
|
+
if (!line) return;
|
|
641191
|
+
entry.activity.push(line);
|
|
641192
|
+
if (entry.activity.length > maxLines) {
|
|
641193
|
+
entry.activity.splice(0, entry.activity.length - maxLines);
|
|
641194
|
+
}
|
|
641195
|
+
entry.updatedAt = Date.now();
|
|
641196
|
+
}
|
|
641197
|
+
function buildSubAgentLiveBlockLines(sourceEntries, width, phase, truecolor = supportsTruecolor()) {
|
|
641198
|
+
const entries = Array.from(sourceEntries).slice(-MAX_PREVIEW_AGENTS);
|
|
641199
|
+
if (entries.length === 0) return [];
|
|
641200
|
+
const w = Math.max(48, Math.floor(width));
|
|
641201
|
+
const inner = Math.max(1, w - 4);
|
|
641202
|
+
const primary = entries.find((entry) => entry.status === "running") ?? entries[0];
|
|
641203
|
+
const title = " Sub-agent activity ";
|
|
641204
|
+
const top = `╭─┤${title}├${"─".repeat(Math.max(0, w - 5 - title.length))}╮`;
|
|
641205
|
+
const bottom = `╰${"─".repeat(Math.max(0, w - 2))}╯`;
|
|
641206
|
+
const lines = [paint(top, primary.stage, phase, 0, truecolor)];
|
|
641207
|
+
for (const entry of entries) {
|
|
641208
|
+
const icon = statusIcon(entry.status);
|
|
641209
|
+
const label = entry.label || entry.id;
|
|
641210
|
+
const state = entry.status === "running" ? `${stageLabel2(entry.stage)}${entry.detail ? ` ${entry.detail}` : ""}` : entry.status;
|
|
641211
|
+
const activity = entry.activity.at(-1) ?? "waiting for activity";
|
|
641212
|
+
lines.push(
|
|
641213
|
+
contentRow(
|
|
641214
|
+
`${icon} ${label} · ${state}`,
|
|
641215
|
+
inner,
|
|
641216
|
+
entry.stage,
|
|
641217
|
+
phase,
|
|
641218
|
+
truecolor
|
|
641219
|
+
)
|
|
641220
|
+
);
|
|
641221
|
+
lines.push(
|
|
641222
|
+
contentRow(
|
|
641223
|
+
` └─ ${activity}`,
|
|
641224
|
+
inner,
|
|
641225
|
+
entry.stage,
|
|
641226
|
+
phase,
|
|
641227
|
+
truecolor
|
|
641228
|
+
)
|
|
641229
|
+
);
|
|
641230
|
+
}
|
|
641231
|
+
lines.push(paint(bottom, primary.stage, phase, 0, truecolor));
|
|
641232
|
+
return lines;
|
|
641233
|
+
}
|
|
641234
|
+
function contentRow(value2, width, stage2, phase, truecolor) {
|
|
641235
|
+
return `│ ${paint(fit2(value2, width), stage2, phase, 1, truecolor)} │`;
|
|
641236
|
+
}
|
|
641237
|
+
function paint(value2, stage2, phase, offset, truecolor) {
|
|
641238
|
+
let out = "";
|
|
641239
|
+
const chars = Array.from(value2);
|
|
641240
|
+
for (let i2 = 0; i2 < chars.length; i2++) {
|
|
641241
|
+
const char = chars[i2];
|
|
641242
|
+
if (truecolor) {
|
|
641243
|
+
const [r2, g, b] = stageGradientRgb(stage2, i2 + offset, phase);
|
|
641244
|
+
out += `\x1B[38;2;${r2};${g};${b}m${char}`;
|
|
641245
|
+
} else {
|
|
641246
|
+
out += `\x1B[38;5;${STAGE_FALLBACK_COLOR[stage2]}m${char}`;
|
|
641247
|
+
}
|
|
641248
|
+
}
|
|
641249
|
+
return `${out}\x1B[0m`;
|
|
641250
|
+
}
|
|
641251
|
+
function fit2(value2, width) {
|
|
641252
|
+
const plain = value2.replace(ANSI_RE2, "").replace(/\s+$/g, "");
|
|
641253
|
+
const chars = Array.from(plain);
|
|
641254
|
+
if (chars.length > width) {
|
|
641255
|
+
return `${chars.slice(0, Math.max(0, width - 1)).join("")}…`;
|
|
641256
|
+
}
|
|
641257
|
+
return plain + " ".repeat(Math.max(0, width - chars.length));
|
|
641258
|
+
}
|
|
641259
|
+
function statusIcon(status) {
|
|
641260
|
+
switch (status) {
|
|
641261
|
+
case "completed":
|
|
641262
|
+
return "✓";
|
|
641263
|
+
case "failed":
|
|
641264
|
+
return "✗";
|
|
641265
|
+
case "paused":
|
|
641266
|
+
case "stopped":
|
|
641267
|
+
return "○";
|
|
641268
|
+
default:
|
|
641269
|
+
return "●";
|
|
641270
|
+
}
|
|
641271
|
+
}
|
|
641272
|
+
var ANSI_RE2, MAX_PREVIEW_AGENTS, MAX_ACTIVITY_CHARS, STAGE_FALLBACK_COLOR;
|
|
641273
|
+
var init_sub_agent_live_block = __esm({
|
|
641274
|
+
"packages/cli/src/tui/sub-agent-live-block.ts"() {
|
|
641275
|
+
init_stageIndicator();
|
|
641276
|
+
ANSI_RE2 = /\x1B\[[0-?]*[ -/]*[@-~]|\x1B\].*?(?:\x07|\x1B\\)/g;
|
|
641277
|
+
MAX_PREVIEW_AGENTS = 4;
|
|
641278
|
+
MAX_ACTIVITY_CHARS = 220;
|
|
641279
|
+
STAGE_FALLBACK_COLOR = {
|
|
641280
|
+
idle: 39,
|
|
641281
|
+
planning: 141,
|
|
641282
|
+
tool_call: 45,
|
|
641283
|
+
reading: 39,
|
|
641284
|
+
searching: 129,
|
|
641285
|
+
editing: 42,
|
|
641286
|
+
writing: 43,
|
|
641287
|
+
testing: 82,
|
|
641288
|
+
building: 220,
|
|
641289
|
+
verifying: 214,
|
|
641290
|
+
reflecting: 177,
|
|
641291
|
+
compacting: 51,
|
|
641292
|
+
adversary_audit: 207,
|
|
641293
|
+
blocked: 208,
|
|
641294
|
+
completed: 46,
|
|
641295
|
+
failed: 196
|
|
641296
|
+
};
|
|
641297
|
+
}
|
|
641298
|
+
});
|
|
641299
|
+
|
|
640793
641300
|
// packages/cli/src/tui/tui-tasks-renderer.ts
|
|
640794
641301
|
var tui_tasks_renderer_exports = {};
|
|
640795
641302
|
__export(tui_tasks_renderer_exports, {
|
|
@@ -643427,6 +643934,7 @@ __export(status_bar_exports, {
|
|
|
643427
643934
|
refreshThemeVars: () => refreshThemeVars,
|
|
643428
643935
|
setTermTitleWriter: () => setTermTitleWriter,
|
|
643429
643936
|
setTerminalTitle: () => setTerminalTitle,
|
|
643937
|
+
stripSubAgentPrefix: () => stripSubAgentPrefix,
|
|
643430
643938
|
unlockFooterRedraws: () => unlockFooterRedraws
|
|
643431
643939
|
});
|
|
643432
643940
|
import { basename as basename30, dirname as dirname44 } from "node:path";
|
|
@@ -643451,7 +643959,8 @@ function headerTelegramFg() {
|
|
|
643451
643959
|
return themeMode() === "system" ? "\x1B[39m" : "\x1B[38;5;45m";
|
|
643452
643960
|
}
|
|
643453
643961
|
function stripSubAgentPrefix(label) {
|
|
643454
|
-
|
|
643962
|
+
let stripped = label.replace(/^\s*sub[-\s]?agents?\b[\s:_–—-]*/i, "").trim();
|
|
643963
|
+
stripped = stripped.replace(/^omnius-/i, "").trim();
|
|
643455
643964
|
return stripped.length > 0 ? stripped : label.trim();
|
|
643456
643965
|
}
|
|
643457
643966
|
function xterm256ToRgb2(i2) {
|
|
@@ -643549,6 +644058,7 @@ var init_status_bar = __esm({
|
|
|
643549
644058
|
"packages/cli/src/tui/status-bar.ts"() {
|
|
643550
644059
|
init_render();
|
|
643551
644060
|
init_stageIndicator();
|
|
644061
|
+
init_sub_agent_live_block();
|
|
643552
644062
|
init_tui_tasks_renderer();
|
|
643553
644063
|
init_braille_spinner();
|
|
643554
644064
|
init_project_context();
|
|
@@ -643789,6 +644299,8 @@ var init_status_bar = __esm({
|
|
|
643789
644299
|
_activeViewId = "main";
|
|
643790
644300
|
_headerExpanded = false;
|
|
643791
644301
|
// toggles sub-agent / scroll info below header
|
|
644302
|
+
_subAgentLiveBlockId = "sub-agent-live-preview";
|
|
644303
|
+
_subAgentLiveBlockAppended = false;
|
|
643792
644304
|
// Virtual scrollback buffer — stores content lines for Page Up/Down scrolling.
|
|
643793
644305
|
// Since we're in alternate screen buffer, there's no native scrollback.
|
|
643794
644306
|
// NOTE: _contentLines is now a reference to the ACTIVE view's buffer.
|
|
@@ -644401,6 +644913,46 @@ var init_status_bar = __esm({
|
|
|
644401
644913
|
* - Category A: Version + menu buttons (help/voice/model/endpoint/sponsor)
|
|
644402
644914
|
* - Category B: Systems (agents/voice status/nexus status)
|
|
644403
644915
|
* Each category paginates independently across N pages. */
|
|
644916
|
+
/** Filled header button whose hue band follows the child agent's current action. */
|
|
644917
|
+
paintAgentButton(content, stage2, active) {
|
|
644918
|
+
const useTruecolor = supportsTruecolor();
|
|
644919
|
+
const chars = Array.from(content);
|
|
644920
|
+
let body = "";
|
|
644921
|
+
for (let i2 = 0; i2 < chars.length; i2++) {
|
|
644922
|
+
const char = chars[i2];
|
|
644923
|
+
if (useTruecolor) {
|
|
644924
|
+
const [r2, g, b] = stageGradientRgb(stage2, i2, this._stagePhase);
|
|
644925
|
+
const luma = 0.299 * r2 + 0.587 * g + 0.114 * b;
|
|
644926
|
+
const fg2 = luma >= 140 ? "\x1B[38;2;16;16;16m" : "\x1B[38;2;255;255;255m";
|
|
644927
|
+
body += `${active ? "\x1B[1m" : ""}${fg2}\x1B[48;2;${r2};${g};${b}m${char}\x1B[0m`;
|
|
644928
|
+
} else {
|
|
644929
|
+
const fallback = stageFallbackColor(stage2);
|
|
644930
|
+
body += `${active ? "\x1B[1m" : ""}\x1B[38;5;${contrastTextColor(fallback)}m\x1B[48;5;${fallback}m${char}\x1B[0m`;
|
|
644931
|
+
}
|
|
644932
|
+
}
|
|
644933
|
+
const [lr, lg, lb] = stageGradientRgb(stage2, 0, this._stagePhase);
|
|
644934
|
+
const leftBorder = useTruecolor ? `\x1B[38;2;${lr};${lg};${lb}m` : `\x1B[38;5;${stageFallbackColor(stage2)}m`;
|
|
644935
|
+
const [rr, rg, rb] = stageGradientRgb(
|
|
644936
|
+
stage2,
|
|
644937
|
+
Math.max(0, chars.length - 1),
|
|
644938
|
+
this._stagePhase
|
|
644939
|
+
);
|
|
644940
|
+
const rightBorder = useTruecolor ? `\x1B[38;2;${rr};${rg};${rb}m` : `\x1B[38;5;${stageFallbackColor(stage2)}m`;
|
|
644941
|
+
return `${leftBorder}${HEADER_BUTTON_LEFT}${RESET4}` + body + `${RESET4}${PANEL_BG_SEQ}${rightBorder}${HEADER_BUTTON_RIGHT}${RESET4}${PANEL_BG_SEQ}`;
|
|
644942
|
+
}
|
|
644943
|
+
paintAgentText(value2, stage2, offset = 0) {
|
|
644944
|
+
const chars = Array.from(value2);
|
|
644945
|
+
let out = "";
|
|
644946
|
+
for (let i2 = 0; i2 < chars.length; i2++) {
|
|
644947
|
+
if (supportsTruecolor()) {
|
|
644948
|
+
const [r2, g, b] = stageGradientRgb(stage2, i2 + offset, this._stagePhase);
|
|
644949
|
+
out += `\x1B[38;2;${r2};${g};${b}m${chars[i2]}`;
|
|
644950
|
+
} else {
|
|
644951
|
+
out += `\x1B[38;5;${stageFallbackColor(stage2)}m${chars[i2]}`;
|
|
644952
|
+
}
|
|
644953
|
+
}
|
|
644954
|
+
return `${out}${RESET4}`;
|
|
644955
|
+
}
|
|
644404
644956
|
_rebuildHeaderPanels() {
|
|
644405
644957
|
this._headerPanels = [];
|
|
644406
644958
|
const savedIdx = this._headerPanelIndex;
|
|
@@ -644412,12 +644964,6 @@ var init_status_bar = __esm({
|
|
|
644412
644964
|
const decorateMenuButton = (cmd, label) => {
|
|
644413
644965
|
return `${HEADER_BUTTON_GLYPH_FG}${HEADER_BUTTON_LEFT}\x1B[0m${HEADER_BUTTON_BG}${HEADER_BUTTON_FG}${label}\x1B[0m${PANEL_BG_SEQ}${HEADER_BUTTON_GLYPH_FG}${HEADER_BUTTON_RIGHT}\x1B[0m${PANEL_BG_SEQ}`;
|
|
644414
644966
|
};
|
|
644415
|
-
const decorateAgentButton = (content, color, active) => {
|
|
644416
|
-
const bg = `\x1B[48;5;${color}m`;
|
|
644417
|
-
const fg2 = `\x1B[38;5;${contrastTextColor(color)}m`;
|
|
644418
|
-
const weight = active ? "\x1B[1m" : "";
|
|
644419
|
-
return `\x1B[38;5;${color}m${HEADER_BUTTON_LEFT}\x1B[0m${weight}${fg2}${bg}${content}\x1B[0m${PANEL_BG_SEQ}\x1B[38;5;${color}m${HEADER_BUTTON_RIGHT}\x1B[0m${PANEL_BG_SEQ}`;
|
|
644420
|
-
};
|
|
644421
644967
|
const renderBtn = (cmd, label) => {
|
|
644422
644968
|
return linkify(cmd, decorateMenuButton(cmd, label));
|
|
644423
644969
|
};
|
|
@@ -644505,9 +645051,8 @@ var init_status_bar = __esm({
|
|
|
644505
645051
|
if (view.id === "main" && this._activeViewId === "main") continue;
|
|
644506
645052
|
const icon = view.status === "running" ? "●" : view.status === "completed" ? "✓" : view.status === "failed" ? "✗" : "○";
|
|
644507
645053
|
const content = ` ${trunc3(view.label)} ${icon} `;
|
|
644508
|
-
const viewColor = view.colorCode ?? (view.type === "telegram" ? 45 : 213);
|
|
644509
645054
|
const active = view.id === this._activeViewId;
|
|
644510
|
-
const btn =
|
|
645055
|
+
const btn = this.paintAgentButton(content, view.stage, active);
|
|
644511
645056
|
sysItems.push({
|
|
644512
645057
|
render: () => linkify(`view:${view.id}`, btn) + " ",
|
|
644513
645058
|
w: content.length + 2 + 1
|
|
@@ -644758,10 +645303,24 @@ var init_status_bar = __esm({
|
|
|
644758
645303
|
buf += `\x1B[${subRow};1H${PANEL_BG_SEQ}\x1B[2K`;
|
|
644759
645304
|
buf += `${BOX_FG}│${RESET4}${PANEL_BG_SEQ}`;
|
|
644760
645305
|
buf += `\x1B[38;5;${TEXT_DIM}m${PANEL_BG_SEQ}`;
|
|
644761
|
-
|
|
644762
|
-
|
|
644763
|
-
|
|
644764
|
-
|
|
645306
|
+
if (this._agentViews.size > 1) {
|
|
645307
|
+
let used = 1;
|
|
645308
|
+
for (const view of Array.from(this._agentViews.values()).filter(
|
|
645309
|
+
(candidate) => candidate.id !== "main"
|
|
645310
|
+
)) {
|
|
645311
|
+
const icon = view.status === "running" ? "●" : view.status === "completed" ? "✓" : view.status === "failed" ? "✗" : "○";
|
|
645312
|
+
const raw = `${icon} ${view.label}`;
|
|
645313
|
+
const gap = used > 1 ? " " : " ";
|
|
645314
|
+
const remaining = Math.max(0, w - 2 - used);
|
|
645315
|
+
if (remaining <= 0) break;
|
|
645316
|
+
const clipped = raw.length > remaining ? `${raw.slice(0, Math.max(0, remaining - 1))}…` : raw;
|
|
645317
|
+
buf += `${PANEL_BG_SEQ}${this.paintAgentText(`${gap}${clipped}`, view.stage, used)}`;
|
|
645318
|
+
used += gap.length + clipped.length;
|
|
645319
|
+
if (clipped !== raw) break;
|
|
645320
|
+
}
|
|
645321
|
+
} else {
|
|
645322
|
+
buf += ` ${NO_SUB_AGENTS_HEADER_LABEL.trim()}`;
|
|
645323
|
+
}
|
|
644765
645324
|
buf += `\x1B[${subRow};${w}H${BOX_FG}│${RESET4}${PANEL_BG_SEQ}`;
|
|
644766
645325
|
const scrollRow = subRow + 1;
|
|
644767
645326
|
let expandedBottom = `${BOX_BL3}${BOX_H3.repeat(w - 2)}${BOX_BR3}`;
|
|
@@ -644902,6 +645461,9 @@ var init_status_bar = __esm({
|
|
|
644902
645461
|
this.advanceStagePhase();
|
|
644903
645462
|
this.renderFooterPreserveCursor();
|
|
644904
645463
|
refreshTuiTasksAnimationFrame();
|
|
645464
|
+
if (this._agentViews.size > 1 && (String(this.currentHeaderPanel).startsWith("sys-") || this._headerExpanded)) {
|
|
645465
|
+
this.refreshHeaderContent();
|
|
645466
|
+
}
|
|
644905
645467
|
}, _StatusBar.FOOTER_ANIMATION_INTERVAL_MS);
|
|
644906
645468
|
this._footerAnimationTimer.unref?.();
|
|
644907
645469
|
}
|
|
@@ -645478,9 +646040,13 @@ var init_status_bar = __esm({
|
|
|
645478
646040
|
scrollOffset: 0,
|
|
645479
646041
|
status: "running",
|
|
645480
646042
|
taskSummary: "",
|
|
645481
|
-
startedAt: Date.now()
|
|
646043
|
+
startedAt: Date.now(),
|
|
646044
|
+
stage: "idle",
|
|
646045
|
+
activity: [],
|
|
646046
|
+
updatedAt: Date.now()
|
|
645482
646047
|
});
|
|
645483
646048
|
}
|
|
646049
|
+
if (this._agentViews.size > 1) this.ensureSubAgentLiveBlock();
|
|
645484
646050
|
setTermSize(process.stdout.rows ?? 24, process.stdout.columns ?? 80);
|
|
645485
646051
|
setFooterMetricsVisible(this._footerMetricsVisible);
|
|
645486
646052
|
this._prevTermRows = termRows();
|
|
@@ -646094,8 +646660,101 @@ var init_status_bar = __esm({
|
|
|
646094
646660
|
}, 1500);
|
|
646095
646661
|
}
|
|
646096
646662
|
// ── Agent View Management (WO-NA1) ────────────────────────────
|
|
646663
|
+
/** Keep one compact, live child-agent preview in the MAIN view. */
|
|
646664
|
+
ensureSubAgentLiveBlock() {
|
|
646665
|
+
if (!this.active || !this._agentViews.has("main") || this._agentViews.size <= 1)
|
|
646666
|
+
return;
|
|
646667
|
+
if (this._subAgentLiveBlockAppended) return;
|
|
646668
|
+
this.registerDynamicBlock(
|
|
646669
|
+
this._subAgentLiveBlockId,
|
|
646670
|
+
(width) => buildSubAgentLiveBlockLines(
|
|
646671
|
+
Array.from(this._agentViews.values()).filter((view) => view.id !== "main"),
|
|
646672
|
+
width,
|
|
646673
|
+
this._stagePhase
|
|
646674
|
+
)
|
|
646675
|
+
);
|
|
646676
|
+
this.appendDynamicBlockToAgentView("main", this._subAgentLiveBlockId);
|
|
646677
|
+
this._subAgentLiveBlockAppended = true;
|
|
646678
|
+
}
|
|
646679
|
+
removeSubAgentLiveBlock() {
|
|
646680
|
+
if (!this._subAgentLiveBlockAppended) return;
|
|
646681
|
+
const main2 = this._agentViews.get("main");
|
|
646682
|
+
const marker = `${this.DYNAMIC_BLOCK_MARK_PREFIX}${this._subAgentLiveBlockId}${this.DYNAMIC_BLOCK_MARK_SUFFIX}`;
|
|
646683
|
+
if (main2) {
|
|
646684
|
+
for (let i2 = main2.contentLines.length - 1; i2 >= 0; i2--) {
|
|
646685
|
+
if (main2.contentLines[i2] === marker) main2.contentLines.splice(i2, 1);
|
|
646686
|
+
}
|
|
646687
|
+
}
|
|
646688
|
+
this.unregisterDynamicBlock(this._subAgentLiveBlockId);
|
|
646689
|
+
this._subAgentLiveBlockAppended = false;
|
|
646690
|
+
if (this.active && this._activeViewId === "main") {
|
|
646691
|
+
this.markContentMutated();
|
|
646692
|
+
this.repaintContent();
|
|
646693
|
+
}
|
|
646694
|
+
}
|
|
646695
|
+
/** Update a child-agent's action state and rolling live preview line. */
|
|
646696
|
+
updateAgentViewActivity(id2, stage2, detail, activity) {
|
|
646697
|
+
const view = this._agentViews.get(id2);
|
|
646698
|
+
if (!view || view.id === "main") return;
|
|
646699
|
+
view.stage = stage2;
|
|
646700
|
+
view.stageDetail = detail?.trim() || void 0;
|
|
646701
|
+
view.updatedAt = Date.now();
|
|
646702
|
+
if (activity) appendSubAgentActivity(view, activity);
|
|
646703
|
+
this.ensureSubAgentLiveBlock();
|
|
646704
|
+
if (this.active) {
|
|
646705
|
+
this.renderAgentTabs();
|
|
646706
|
+
if (this._headerExpanded) this.refreshHeaderContent();
|
|
646707
|
+
this.refreshDynamicBlocks();
|
|
646708
|
+
}
|
|
646709
|
+
}
|
|
646710
|
+
/** Structured-event adapter used by in-process child runners. */
|
|
646711
|
+
updateAgentViewEvent(id2, event, activity) {
|
|
646712
|
+
const view = this._agentViews.get(id2);
|
|
646713
|
+
if (!view) return;
|
|
646714
|
+
const transition = stageForAgentEvent(event);
|
|
646715
|
+
this.updateAgentViewActivity(
|
|
646716
|
+
id2,
|
|
646717
|
+
transition?.stage ?? view.stage,
|
|
646718
|
+
transition?.detail ?? view.stageDetail,
|
|
646719
|
+
activity
|
|
646720
|
+
);
|
|
646721
|
+
}
|
|
646722
|
+
/** Forward a raw full-sub-agent stdout chunk into the same state model. */
|
|
646723
|
+
recordAgentOutput(id2, text2) {
|
|
646724
|
+
const line = text2.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "").split(/\r?\n/).map((value2) => value2.trim()).filter(Boolean).at(-1);
|
|
646725
|
+
if (!line) {
|
|
646726
|
+
this.writeToAgentView(id2, text2);
|
|
646727
|
+
return;
|
|
646728
|
+
}
|
|
646729
|
+
const lower = line.toLowerCase();
|
|
646730
|
+
let stage2 = "tool_call";
|
|
646731
|
+
if (/\b(error|failed|failure|exception|blocked)\b/.test(lower)) stage2 = "failed";
|
|
646732
|
+
else if (/\b(complete|completed|done|success|succeeded)\b/.test(lower)) stage2 = "completed";
|
|
646733
|
+
else if (/\b(file_read|read|grep|search|find)\b/.test(lower)) stage2 = "reading";
|
|
646734
|
+
else if (/\b(file_write|file_edit|file_patch|batch_edit|write|edit|patch)\b/.test(lower)) stage2 = "writing";
|
|
646735
|
+
else if (/\b(shell|build|test|compile|npm|pnpm|pio)\b/.test(lower)) stage2 = "building";
|
|
646736
|
+
this.updateAgentViewActivity(id2, stage2, line.slice(0, 40), line);
|
|
646737
|
+
this.writeToAgentView(id2, text2);
|
|
646738
|
+
}
|
|
646097
646739
|
/** Register a new sub-agent view with its own content buffer */
|
|
646098
646740
|
registerAgentView(id2, label, type, taskSummary) {
|
|
646741
|
+
const existing = this._agentViews.get(id2);
|
|
646742
|
+
if (existing) {
|
|
646743
|
+
if (existing.id !== "main") {
|
|
646744
|
+
const cleanExistingLabel = stripSubAgentPrefix(existing.label);
|
|
646745
|
+
existing.label = cleanExistingLabel || stripSubAgentPrefix(label);
|
|
646746
|
+
}
|
|
646747
|
+
existing.taskSummary = taskSummary ?? existing.taskSummary;
|
|
646748
|
+
existing.status = "running";
|
|
646749
|
+
existing.updatedAt = Date.now();
|
|
646750
|
+
this.ensureSubAgentLiveBlock();
|
|
646751
|
+
if (this.active) {
|
|
646752
|
+
this._rebuildHeaderPanels?.();
|
|
646753
|
+
this.renderFooterAndPositionInput();
|
|
646754
|
+
this.refreshHeaderContent();
|
|
646755
|
+
}
|
|
646756
|
+
return;
|
|
646757
|
+
}
|
|
646099
646758
|
this._agentViews.set(id2, {
|
|
646100
646759
|
id: id2,
|
|
646101
646760
|
label: stripSubAgentPrefix(label),
|
|
@@ -646105,9 +646764,14 @@ var init_status_bar = __esm({
|
|
|
646105
646764
|
status: "running",
|
|
646106
646765
|
taskSummary: taskSummary ?? "",
|
|
646107
646766
|
startedAt: Date.now(),
|
|
646108
|
-
colorCode: type === "telegram" ? 45 : this.nextAgentColor()
|
|
646767
|
+
colorCode: type === "telegram" ? 45 : this.nextAgentColor(),
|
|
646768
|
+
stage: "planning",
|
|
646769
|
+
stageDetail: "spawn",
|
|
646770
|
+
activity: ["spawned; waiting for first action"],
|
|
646771
|
+
updatedAt: Date.now()
|
|
646109
646772
|
});
|
|
646110
646773
|
if (this.active) {
|
|
646774
|
+
this.ensureSubAgentLiveBlock();
|
|
646111
646775
|
this.applyScrollRegion();
|
|
646112
646776
|
this._rebuildHeaderPanels?.();
|
|
646113
646777
|
this.renderFooterAndPositionInput();
|
|
@@ -646117,6 +646781,7 @@ var init_status_bar = __esm({
|
|
|
646117
646781
|
/** Remove a sub-agent view */
|
|
646118
646782
|
unregisterAgentView(id2) {
|
|
646119
646783
|
this._agentViews.delete(id2);
|
|
646784
|
+
if (this._agentViews.size <= 1) this.removeSubAgentLiveBlock();
|
|
646120
646785
|
if (this._activeViewId === id2) this.switchToView("main");
|
|
646121
646786
|
if (this.active) {
|
|
646122
646787
|
this.applyScrollRegion();
|
|
@@ -646130,9 +646795,27 @@ var init_status_bar = __esm({
|
|
|
646130
646795
|
const view = this._agentViews.get(id2);
|
|
646131
646796
|
if (!view) return;
|
|
646132
646797
|
view.status = status;
|
|
646133
|
-
if (status === "completed"
|
|
646798
|
+
if (status === "completed") {
|
|
646134
646799
|
view.completedAt = Date.now();
|
|
646135
|
-
|
|
646800
|
+
view.stage = "completed";
|
|
646801
|
+
view.stageDetail = "done";
|
|
646802
|
+
appendSubAgentActivity(view, "completed");
|
|
646803
|
+
} else if (status === "failed") {
|
|
646804
|
+
view.completedAt = Date.now();
|
|
646805
|
+
view.stage = "failed";
|
|
646806
|
+
view.stageDetail = "failed";
|
|
646807
|
+
appendSubAgentActivity(view, "failed");
|
|
646808
|
+
} else if (status === "paused" || status === "stopped") {
|
|
646809
|
+
view.stage = "blocked";
|
|
646810
|
+
view.stageDetail = status;
|
|
646811
|
+
appendSubAgentActivity(view, status);
|
|
646812
|
+
}
|
|
646813
|
+
view.updatedAt = Date.now();
|
|
646814
|
+
if (this.active) {
|
|
646815
|
+
this.renderAgentTabs();
|
|
646816
|
+
if (this._headerExpanded) this.refreshHeaderContent();
|
|
646817
|
+
this.refreshDynamicBlocks();
|
|
646818
|
+
}
|
|
646136
646819
|
}
|
|
646137
646820
|
/** Switch which agent's content buffer is displayed */
|
|
646138
646821
|
switchToView(id2) {
|
|
@@ -653078,9 +653761,9 @@ function formatExpandedContextDiagnostic(specs, math) {
|
|
|
653078
653761
|
memBits.push(`RAM ${fmtGB(specs.availableRamGB)}/${fmtGB(specs.totalRamGB)}${specs.unifiedMemory ? " unified" : ""}`);
|
|
653079
653762
|
const mem = memBits.join(", ");
|
|
653080
653763
|
const kv = `KV ${fmtKB(math.kvBytesPerToken)}/tok (${math.kvSource})`;
|
|
653081
|
-
const
|
|
653764
|
+
const fit4 = `fit ${fmtK(math.memoryFit)}, arch ${math.archCtx !== null ? fmtK(math.archCtx) : "n/a"}, floor ${fmtK(math.floor)}`;
|
|
653082
653765
|
const limit = `→ ${fmtK(math.numCtx)} (${math.limitedBy === "floor" ? "min floor" : math.limitedBy === "arch" ? "arch-capped" : "memory-fit"})`;
|
|
653083
|
-
return `[${mem} | model ${fmtGB(math.modelSizeGB)} | ${kv} | ${
|
|
653766
|
+
return `[${mem} | model ${fmtGB(math.modelSizeGB)} | ${kv} | ${fit4} ${limit}]`;
|
|
653084
653767
|
}
|
|
653085
653768
|
async function ensureExpandedContext(modelName, backendUrl2) {
|
|
653086
653769
|
if (modelName.includes("cloud") || modelName.includes(":cloud")) {
|
|
@@ -653359,7 +654042,7 @@ export PATH="${binDir}:$PATH" # Added by omnius for nvim
|
|
|
653359
654042
|
} catch {
|
|
653360
654043
|
}
|
|
653361
654044
|
}
|
|
653362
|
-
var execAsync2, OMNIUS_FIRST_RUN_BANNER,
|
|
654045
|
+
var execAsync2, OMNIUS_FIRST_RUN_BANNER, ANSI_RE3, visibleLen2, SETUP_MODEL_VARIANTS, _toolSupportCache, EXPANDED_VARIANT_MIN_NUM_CTX, _cloudflaredInstallPromise;
|
|
653363
654046
|
var init_setup = __esm({
|
|
653364
654047
|
"packages/cli/src/tui/setup.ts"() {
|
|
653365
654048
|
init_model_picker();
|
|
@@ -653378,8 +654061,8 @@ var init_setup = __esm({
|
|
|
653378
654061
|
"░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ",
|
|
653379
654062
|
" ░▒▓██████▓▒░░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓██████▓▒░░▒▓███████▓▒░ "
|
|
653380
654063
|
].join("\n");
|
|
653381
|
-
|
|
653382
|
-
visibleLen2 = (value2) => Array.from(value2.replace(
|
|
654064
|
+
ANSI_RE3 = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
654065
|
+
visibleLen2 = (value2) => Array.from(value2.replace(ANSI_RE3, "")).length;
|
|
653383
654066
|
SETUP_MODEL_VARIANTS = [
|
|
653384
654067
|
{ tag: "robit/ornith:9b", sizeGB: 6.6, label: "9B params (6.6 GB) - recommended minimum", cloud: false },
|
|
653385
654068
|
{ tag: "robit/ornith:35b", sizeGB: 24, label: "35B params (24 GB) - recommended on 32GB+ unified memory/VRAM", cloud: false }
|
|
@@ -674050,12 +674733,12 @@ function cad3dFitIcon(score) {
|
|
|
674050
674733
|
if (score >= 40) return c3.yellow("△");
|
|
674051
674734
|
return c3.red("✖");
|
|
674052
674735
|
}
|
|
674053
|
-
function cad3dModelDetail(spec,
|
|
674736
|
+
function cad3dModelDetail(spec, fit4) {
|
|
674054
674737
|
const download = spec.resources.approxDownloadGB ? `~${spec.resources.approxDownloadGB}GB` : "size unknown";
|
|
674055
674738
|
const vram = spec.resources.recommendedVramGB ? `${spec.resources.recommendedVramGB}GB VRAM rec` : "VRAM varies";
|
|
674056
674739
|
const license = spec.hf.license ? `license ${spec.hf.license}` : "license unknown";
|
|
674057
674740
|
const token = spec.deployment.requiresToken ? "requires HF token" : "no token gate";
|
|
674058
|
-
return `${
|
|
674741
|
+
return `${fit4.label} · ${spec.backend} · ${download} · ${vram} · ${license} · ${token}`;
|
|
674059
674742
|
}
|
|
674060
674743
|
async function startCad3dViewerFromCommand(rawPath) {
|
|
674061
674744
|
const viewer = await startCadModelViewer(
|
|
@@ -674071,11 +674754,11 @@ async function showCad3dModelsMenu(ctx3, hasLocal, mode) {
|
|
|
674071
674754
|
const active = mode === "cad" ? settings.cadModel : settings.model3dModel;
|
|
674072
674755
|
const currentViewer2 = getCurrentCadModelViewer();
|
|
674073
674756
|
const buildItem = (entry) => {
|
|
674074
|
-
const
|
|
674757
|
+
const fit4 = rateCad3dModelForHardware(entry.spec, specs);
|
|
674075
674758
|
return {
|
|
674076
674759
|
key: `model:${entry.spec.id}`,
|
|
674077
|
-
label: `${cad3dFitIcon(
|
|
674078
|
-
detail: cad3dModelDetail(entry.spec,
|
|
674760
|
+
label: `${cad3dFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${entry.spec.label}`,
|
|
674761
|
+
detail: cad3dModelDetail(entry.spec, fit4)
|
|
674079
674762
|
};
|
|
674080
674763
|
};
|
|
674081
674764
|
const items = [
|
|
@@ -674110,11 +674793,11 @@ async function showCad3dModelsMenu(ctx3, hasLocal, mode) {
|
|
|
674110
674793
|
const patch = mode === "cad" ? { cadModel: id2, cadBackend: entry.spec.backend } : { model3dModel: id2, model3dBackend: entry.spec.backend };
|
|
674111
674794
|
const save3 = hasLocal ? ctx3.saveLocalSettings : ctx3.saveSettings;
|
|
674112
674795
|
save3(patch);
|
|
674113
|
-
const
|
|
674796
|
+
const fit4 = rateCad3dModelForHardware(entry.spec, specs);
|
|
674114
674797
|
renderInfo(
|
|
674115
674798
|
`${mode === "cad" ? "CAD" : "3D"} model: ${id2} (${entry.spec.backend})${hasLocal ? " (project-local)" : ""}`
|
|
674116
674799
|
);
|
|
674117
|
-
renderInfo(`Hardware fit: ${
|
|
674800
|
+
renderInfo(`Hardware fit: ${fit4.score}/100 ${fit4.label} - ${fit4.note}`);
|
|
674118
674801
|
if (entry.spec.resources.approxDownloadGB) {
|
|
674119
674802
|
renderInfo(
|
|
674120
674803
|
`Download estimate: ~${entry.spec.resources.approxDownloadGB}GB in ${unifiedModelStoreDir()}`
|
|
@@ -674265,19 +674948,19 @@ async function renderImageModelList(ctx3) {
|
|
|
674265
674948
|
renderInfo("");
|
|
674266
674949
|
renderInfo(c3.bold(category));
|
|
674267
674950
|
for (const preset of presets) {
|
|
674268
|
-
const
|
|
674951
|
+
const fit4 = rateImagePresetForHardware(preset, specs);
|
|
674269
674952
|
const primary = category === "Primary hyper-realistic baseline" ? c3.cyan(" ★") : "";
|
|
674270
674953
|
const disk = ctx3 ? imageModelDiskStats(ctx3, preset, ollamaSizes) : { downloaded: false, bytes: 0, paths: [] };
|
|
674271
674954
|
const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
|
|
674272
674955
|
renderInfo(
|
|
674273
|
-
`${imageFitIcon(
|
|
674956
|
+
`${imageFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${c3.bold(preset.label)}${primary}${diskInfo}`
|
|
674274
674957
|
);
|
|
674275
674958
|
renderInfo(` id: ${preset.id}`);
|
|
674276
674959
|
renderInfo(
|
|
674277
|
-
` type: ${preset.backend} · ${preset.sizeClass ?? "unknown size"} · ${
|
|
674960
|
+
` type: ${preset.backend} · ${preset.sizeClass ?? "unknown size"} · ${fit4.label}`
|
|
674278
674961
|
);
|
|
674279
674962
|
renderImagePresetDetail(" quality: ", preset.quality ?? preset.note);
|
|
674280
|
-
renderImagePresetDetail(" fit: ",
|
|
674963
|
+
renderImagePresetDetail(" fit: ", fit4.note);
|
|
674281
674964
|
if (preset.deployment)
|
|
674282
674965
|
renderImagePresetDetail(" deploy: ", preset.deployment);
|
|
674283
674966
|
}
|
|
@@ -674420,13 +675103,13 @@ async function showImageModelsMenu(ctx3, hasLocal) {
|
|
|
674420
675103
|
() => /* @__PURE__ */ new Map()
|
|
674421
675104
|
);
|
|
674422
675105
|
const buildModelItem = (preset) => {
|
|
674423
|
-
const
|
|
675106
|
+
const fit4 = rateImagePresetForHardware(preset, specs);
|
|
674424
675107
|
const disk = imageModelDiskStats(ctx3, preset, ollamaSizes);
|
|
674425
675108
|
const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
|
|
674426
675109
|
return {
|
|
674427
675110
|
key: `model:${preset.id}`,
|
|
674428
|
-
label: `${downloaded}${imageFitIcon(
|
|
674429
|
-
detail: `${
|
|
675111
|
+
label: `${downloaded}${imageFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${preset.label}`,
|
|
675112
|
+
detail: `${fit4.score}/100 ${fit4.label} · ${preset.category ?? preset.backend} · ${preset.sizeClass ?? preset.id}${downloadedModelSuffix(disk)}`
|
|
674430
675113
|
};
|
|
674431
675114
|
};
|
|
674432
675115
|
const items = [
|
|
@@ -674511,9 +675194,9 @@ async function showImageModelsMenu(ctx3, hasLocal) {
|
|
|
674511
675194
|
renderInfo(
|
|
674512
675195
|
`Image model: ${model} (${backend})${hasLocal ? " (project-local)" : ""}`
|
|
674513
675196
|
);
|
|
674514
|
-
const
|
|
674515
|
-
if (
|
|
674516
|
-
renderInfo(`Hardware fit: ${
|
|
675197
|
+
const fit4 = preset ? rateImagePresetForHardware(preset, specs) : void 0;
|
|
675198
|
+
if (fit4)
|
|
675199
|
+
renderInfo(`Hardware fit: ${fit4.score}/100 ${fit4.label} — ${fit4.note}`);
|
|
674517
675200
|
if (preset?.install) renderInfo(`Prewarm command: ${preset.install}`);
|
|
674518
675201
|
await prewarmImageModel(ctx3, model, backend);
|
|
674519
675202
|
}
|
|
@@ -674829,19 +675512,19 @@ async function renderVideoModelList(ctx3) {
|
|
|
674829
675512
|
renderInfo("");
|
|
674830
675513
|
renderInfo(c3.bold(category));
|
|
674831
675514
|
for (const preset of presets) {
|
|
674832
|
-
const
|
|
675515
|
+
const fit4 = rateVideoPresetForHardware(preset, specs);
|
|
674833
675516
|
const disk = videoModelDiskStats(ctx3, preset);
|
|
674834
675517
|
const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
|
|
674835
675518
|
renderInfo(
|
|
674836
|
-
`${imageFitIcon(
|
|
675519
|
+
`${imageFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`
|
|
674837
675520
|
);
|
|
674838
675521
|
renderInfo(` id: ${preset.id}`);
|
|
674839
675522
|
renderInfo(
|
|
674840
|
-
` type: ${preset.backend} · ${preset.sizeClass} · ${preset.kinds.join("/")} · ${
|
|
675523
|
+
` type: ${preset.backend} · ${preset.sizeClass} · ${preset.kinds.join("/")} · ${fit4.label}`
|
|
674841
675524
|
);
|
|
674842
675525
|
renderImagePresetDetail(" quality: ", preset.quality);
|
|
674843
675526
|
renderImagePresetDetail(" output: ", preset.output);
|
|
674844
|
-
renderImagePresetDetail(" fit: ",
|
|
675527
|
+
renderImagePresetDetail(" fit: ", fit4.note);
|
|
674845
675528
|
renderImagePresetDetail(" deploy: ", preset.deployment);
|
|
674846
675529
|
if (preset.licenseNote)
|
|
674847
675530
|
renderImagePresetDetail(" license: ", preset.licenseNote);
|
|
@@ -674852,13 +675535,13 @@ async function showVideoModelsMenu(ctx3, hasLocal) {
|
|
|
674852
675535
|
const settings = resolveSettings(ctx3.repoRoot);
|
|
674853
675536
|
const specs = await detectSystemSpecsAsync();
|
|
674854
675537
|
const buildModelItem = (preset) => {
|
|
674855
|
-
const
|
|
675538
|
+
const fit4 = rateVideoPresetForHardware(preset, specs);
|
|
674856
675539
|
const disk = videoModelDiskStats(ctx3, preset);
|
|
674857
675540
|
const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
|
|
674858
675541
|
return {
|
|
674859
675542
|
key: `model:${preset.id}`,
|
|
674860
|
-
label: `${downloaded}${imageFitIcon(
|
|
674861
|
-
detail: `${
|
|
675543
|
+
label: `${downloaded}${imageFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${preset.label}`,
|
|
675544
|
+
detail: `${fit4.label} · ${preset.category} · ${preset.kinds.join("/")}${downloadedModelSuffix(disk)}`
|
|
674862
675545
|
};
|
|
674863
675546
|
};
|
|
674864
675547
|
const items = [
|
|
@@ -674937,8 +675620,8 @@ async function showVideoModelsMenu(ctx3, hasLocal) {
|
|
|
674937
675620
|
`Video model: ${model} (${backend})${hasLocal ? " (project-local)" : ""}`
|
|
674938
675621
|
);
|
|
674939
675622
|
if (preset) {
|
|
674940
|
-
const
|
|
674941
|
-
renderInfo(`Hardware fit: ${
|
|
675623
|
+
const fit4 = rateVideoPresetForHardware(preset, specs);
|
|
675624
|
+
renderInfo(`Hardware fit: ${fit4.score}/100 ${fit4.label} — ${fit4.note}`);
|
|
674942
675625
|
if (preset.licenseNote) renderInfo(`License: ${preset.licenseNote}`);
|
|
674943
675626
|
if (preset.install) renderInfo(`Prewarm command: ${preset.install}`);
|
|
674944
675627
|
}
|
|
@@ -675200,19 +675883,19 @@ async function renderAudioModelList(ctx3, kind) {
|
|
|
675200
675883
|
renderInfo("");
|
|
675201
675884
|
renderInfo(c3.bold(category));
|
|
675202
675885
|
for (const preset of presets) {
|
|
675203
|
-
const
|
|
675886
|
+
const fit4 = rateAudioPresetForHardware(preset, specs);
|
|
675204
675887
|
const disk = audioModelDiskStats(ctx3, preset);
|
|
675205
675888
|
const diskInfo = disk.downloaded ? ` ${c3.green("✓")} ${formatFileSize(disk.bytes)}` : "";
|
|
675206
675889
|
renderInfo(
|
|
675207
|
-
`${audioFitIcon(
|
|
675890
|
+
`${audioFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${c3.bold(preset.label)}${diskInfo}`
|
|
675208
675891
|
);
|
|
675209
675892
|
renderInfo(` id: ${preset.id}`);
|
|
675210
675893
|
renderInfo(
|
|
675211
|
-
` type: ${preset.backend} · ${preset.sizeClass} · ${
|
|
675894
|
+
` type: ${preset.backend} · ${preset.sizeClass} · ${fit4.label}`
|
|
675212
675895
|
);
|
|
675213
675896
|
renderImagePresetDetail(" quality: ", preset.quality);
|
|
675214
675897
|
renderImagePresetDetail(" output: ", preset.output);
|
|
675215
|
-
renderImagePresetDetail(" fit: ",
|
|
675898
|
+
renderImagePresetDetail(" fit: ", fit4.note);
|
|
675216
675899
|
renderImagePresetDetail(" deploy: ", preset.deployment);
|
|
675217
675900
|
}
|
|
675218
675901
|
}
|
|
@@ -675237,13 +675920,13 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
|
|
|
675237
675920
|
const activeModel = activeAudioModel(settings, kind);
|
|
675238
675921
|
const title = kind === "music" ? "Music Generation" : "Sound Generation";
|
|
675239
675922
|
const buildModelItem = (preset) => {
|
|
675240
|
-
const
|
|
675923
|
+
const fit4 = rateAudioPresetForHardware(preset, specs);
|
|
675241
675924
|
const disk = audioModelDiskStats(ctx3, preset);
|
|
675242
675925
|
const downloaded = disk.downloaded ? `${c3.green("✓")} ` : "";
|
|
675243
675926
|
return {
|
|
675244
675927
|
key: `model:${preset.id}`,
|
|
675245
|
-
label: `${downloaded}${audioFitIcon(
|
|
675246
|
-
detail: `${
|
|
675928
|
+
label: `${downloaded}${audioFitIcon(fit4.score)} ${String(fit4.score).padStart(3)}/100 ${preset.label}`,
|
|
675929
|
+
detail: `${fit4.label} · ${preset.category} · ${preset.sizeClass}${downloadedModelSuffix(disk)}`
|
|
675247
675930
|
};
|
|
675248
675931
|
};
|
|
675249
675932
|
const setupItems = kind === "music" ? [
|
|
@@ -675364,8 +676047,8 @@ async function showAudioGenerationMenu(ctx3, hasLocal, kind) {
|
|
|
675364
676047
|
`${kind === "music" ? "Music" : "Sound"} model: ${model} (${backend})${hasLocal ? " (project-local)" : ""}`
|
|
675365
676048
|
);
|
|
675366
676049
|
if (preset) {
|
|
675367
|
-
const
|
|
675368
|
-
renderInfo(`Hardware fit: ${
|
|
676050
|
+
const fit4 = rateAudioPresetForHardware(preset, specs);
|
|
676051
|
+
renderInfo(`Hardware fit: ${fit4.score}/100 ${fit4.label} - ${fit4.note}`);
|
|
675369
676052
|
renderInfo(`Prewarm command: ${preset.install}`);
|
|
675370
676053
|
}
|
|
675371
676054
|
await prewarmAudioModel(ctx3, kind, model, backend);
|
|
@@ -700701,10 +701384,10 @@ ${message2}`)
|
|
|
700701
701384
|
telegramModelMenuItems(generation) {
|
|
700702
701385
|
return this.telegramGenerationModelDescriptors(generation).map((model) => {
|
|
700703
701386
|
const cached = model.cachedBytes > 0 ? `cached ${formatModelBytes(model.cachedBytes)}` : "not downloaded";
|
|
700704
|
-
const
|
|
701387
|
+
const fit4 = model.recommendedVramGB ? `${model.recommendedVramGB}GB VRAM rec` : model.minVramGB ? `${model.minVramGB}GB VRAM min` : "VRAM n/a";
|
|
700705
701388
|
return {
|
|
700706
701389
|
label: model.label,
|
|
700707
|
-
description: `${model.backend} - ${model.category} - ${
|
|
701390
|
+
description: `${model.backend} - ${model.category} - ${fit4} - ${cached}`,
|
|
700708
701391
|
action: {
|
|
700709
701392
|
type: "model_detail",
|
|
700710
701393
|
generation,
|
|
@@ -714814,17 +715497,17 @@ function buildShellLiveBlockLines(state, width) {
|
|
|
714814
715497
|
const body = visibleLines.slice(-state.maxRows);
|
|
714815
715498
|
const rows = [
|
|
714816
715499
|
top,
|
|
714817
|
-
|
|
714818
|
-
|
|
715500
|
+
contentRow2(`$ ${state.command}`, inner),
|
|
715501
|
+
contentRow2("", inner)
|
|
714819
715502
|
];
|
|
714820
715503
|
if (hidden > 0)
|
|
714821
715504
|
rows.push(
|
|
714822
|
-
|
|
715505
|
+
contentRow2(`... ${hidden} earlier line${hidden === 1 ? "" : "s"}`, inner)
|
|
714823
715506
|
);
|
|
714824
715507
|
if (body.length === 0) {
|
|
714825
|
-
rows.push(
|
|
715508
|
+
rows.push(contentRow2("(waiting for output)", inner));
|
|
714826
715509
|
} else {
|
|
714827
|
-
for (const line of body) rows.push(
|
|
715510
|
+
for (const line of body) rows.push(contentRow2(line, inner));
|
|
714828
715511
|
}
|
|
714829
715512
|
rows.push(bottom);
|
|
714830
715513
|
return rows;
|
|
@@ -714836,10 +715519,10 @@ function pushShellLiveLine(state, line) {
|
|
|
714836
715519
|
state.lines.splice(0, state.lines.length - maxStored);
|
|
714837
715520
|
}
|
|
714838
715521
|
}
|
|
714839
|
-
function
|
|
714840
|
-
return `│ ${
|
|
715522
|
+
function contentRow2(value2, inner) {
|
|
715523
|
+
return `│ ${fit3(value2, inner)} │`;
|
|
714841
715524
|
}
|
|
714842
|
-
function
|
|
715525
|
+
function fit3(value2, width) {
|
|
714843
715526
|
const plain = value2.replace(ANSI_OR_OSC_RE, "").replace(/\s+$/g, "");
|
|
714844
715527
|
const chars = Array.from(plain);
|
|
714845
715528
|
if (chars.length > width) {
|
|
@@ -748668,6 +749351,8 @@ function appendSubAgentNoteBox(statusBar, agentId, event, title, metrics2, conte
|
|
|
748668
749351
|
);
|
|
748669
749352
|
}
|
|
748670
749353
|
function writeSubAgentEventForView(statusBar, agentId, event, verbose = false) {
|
|
749354
|
+
const previewLine = formatSubAgentEventForView(event);
|
|
749355
|
+
statusBar.updateAgentViewEvent(agentId, event, previewLine ?? event.type);
|
|
748671
749356
|
switch (event.type) {
|
|
748672
749357
|
case "tool_call": {
|
|
748673
749358
|
subAgentPendingToolCalls.set(agentId, {
|
|
@@ -748751,7 +749436,7 @@ function writeSubAgentEventForView(statusBar, agentId, event, verbose = false) {
|
|
|
748751
749436
|
return true;
|
|
748752
749437
|
}
|
|
748753
749438
|
default: {
|
|
748754
|
-
const line =
|
|
749439
|
+
const line = previewLine;
|
|
748755
749440
|
if (line) statusBar.writeToAgentView(agentId, line);
|
|
748756
749441
|
return Boolean(line);
|
|
748757
749442
|
}
|
|
@@ -750374,7 +751059,7 @@ ${content}
|
|
|
750374
751059
|
});
|
|
750375
751060
|
statusBar.ensureMonitorTimer();
|
|
750376
751061
|
},
|
|
750377
|
-
onViewWrite: (id2, text2) => statusBar.
|
|
751062
|
+
onViewWrite: (id2, text2) => statusBar.recordAgentOutput(id2, text2),
|
|
750378
751063
|
onViewEvent: (id2, event) => writeSubAgentEventForView(statusBar, id2, event, config.verbose),
|
|
750379
751064
|
onViewStatus: (id2, status) => {
|
|
750380
751065
|
statusBar.updateAgentViewStatus(id2, status);
|
|
@@ -750954,40 +751639,9 @@ ${entry.fullContent}`
|
|
|
750954
751639
|
};
|
|
750955
751640
|
runner.onEvent((event) => {
|
|
750956
751641
|
emotionEngine?.appraise(event);
|
|
750957
|
-
|
|
750958
|
-
|
|
750959
|
-
|
|
750960
|
-
if (tn === "file_read" || tn === "structured_read")
|
|
750961
|
-
setStage("reading", tn);
|
|
750962
|
-
else if (tn === "grep_search" || tn === "glob_find" || tn === "web_search" || tn === "web_fetch" || tn === "web_crawl")
|
|
750963
|
-
setStage("searching", tn);
|
|
750964
|
-
else if (tn === "file_write" || tn === "file_edit" || tn === "file_patch" || tn === "batch_edit" || tn === "structured_file")
|
|
750965
|
-
setStage("writing", tn);
|
|
750966
|
-
else if (tn === "shell" || tn === "shell_async" || tn === "run_tests" || tn === "repl_exec")
|
|
750967
|
-
setStage("building", tn);
|
|
750968
|
-
else setStage("tool_call", tn);
|
|
750969
|
-
break;
|
|
750970
|
-
}
|
|
750971
|
-
case "stream_start":
|
|
750972
|
-
setStage("planning");
|
|
750973
|
-
break;
|
|
750974
|
-
case "compaction":
|
|
750975
|
-
setStage("compacting");
|
|
750976
|
-
break;
|
|
750977
|
-
case "debug_adversary":
|
|
750978
|
-
setStage("adversary_audit");
|
|
750979
|
-
break;
|
|
750980
|
-
case "complete":
|
|
750981
|
-
setStage("completed");
|
|
750982
|
-
break;
|
|
750983
|
-
case "error":
|
|
750984
|
-
setStage("failed", event.content?.slice(0, 40));
|
|
750985
|
-
break;
|
|
750986
|
-
case "user_interrupt":
|
|
750987
|
-
setStage("blocked");
|
|
750988
|
-
break;
|
|
750989
|
-
default:
|
|
750990
|
-
break;
|
|
751642
|
+
const stageTransition = stageForAgentEvent(event);
|
|
751643
|
+
if (stageTransition) {
|
|
751644
|
+
setStage(stageTransition.stage, stageTransition.detail);
|
|
750991
751645
|
}
|
|
750992
751646
|
switch (event.type) {
|
|
750993
751647
|
case "tool_call":
|
|
@@ -752406,7 +753060,7 @@ async function startInteractive(config, repoPath2) {
|
|
|
752406
753060
|
});
|
|
752407
753061
|
statusBar.ensureMonitorTimer();
|
|
752408
753062
|
},
|
|
752409
|
-
onViewWrite: (id2, text2) => statusBar.
|
|
753063
|
+
onViewWrite: (id2, text2) => statusBar.recordAgentOutput(id2, text2),
|
|
752410
753064
|
onViewStatus: (id2, status) => {
|
|
752411
753065
|
statusBar.updateAgentViewStatus(id2, status);
|
|
752412
753066
|
const agent = registry2.subAgents.get(id2);
|
|
@@ -752447,7 +753101,7 @@ async function startInteractive(config, repoPath2) {
|
|
|
752447
753101
|
});
|
|
752448
753102
|
statusBar.ensureMonitorTimer();
|
|
752449
753103
|
},
|
|
752450
|
-
onViewWrite: (id2, text2) => statusBar.
|
|
753104
|
+
onViewWrite: (id2, text2) => statusBar.recordAgentOutput(id2, text2),
|
|
752451
753105
|
onViewEvent: (id2, event) => writeSubAgentEventForView(statusBar, id2, event, config.verbose),
|
|
752452
753106
|
onViewStatus: (id2, status) => {
|
|
752453
753107
|
statusBar.updateAgentViewStatus(id2, status);
|
|
@@ -752661,7 +753315,7 @@ ${result.summary}`
|
|
|
752661
753315
|
},
|
|
752662
753316
|
// Stream the full sub-agent's stdout into its toolbar view so the
|
|
752663
753317
|
// clickable tab shows live output instead of staying empty.
|
|
752664
|
-
(text2) => statusBar.
|
|
753318
|
+
(text2) => statusBar.recordAgentOutput(opts.id, text2),
|
|
752665
753319
|
(id2, exitCode) => statusBar.updateAgentViewStatus(
|
|
752666
753320
|
opts.id,
|
|
752667
753321
|
exitCode === 0 ? "completed" : "failed"
|
|
@@ -755250,7 +755904,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
755250
755904
|
);
|
|
755251
755905
|
statusBar.ensureMonitorTimer();
|
|
755252
755906
|
},
|
|
755253
|
-
onWrite: (id2, text2) => statusBar.
|
|
755907
|
+
onWrite: (id2, text2) => statusBar.recordAgentOutput(id2, text2),
|
|
755254
755908
|
onStatus: (id2, status) => {
|
|
755255
755909
|
statusBar.updateAgentViewStatus(id2, status);
|
|
755256
755910
|
const agent = registry2.subAgents.get(id2);
|