omnius 1.0.269 → 1.0.271
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 +247 -54
- package/docs/operations/delay-fix-review.md +153 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -546546,7 +546546,10 @@ var init_agent_tool = __esm({
|
|
|
546546
546546
|
lines.push(prompt);
|
|
546547
546547
|
return lines.join("\n");
|
|
546548
546548
|
})();
|
|
546549
|
-
|
|
546549
|
+
const fullDefault = process.env["OMNIUS_FULL_SUBAGENT_DEFAULT"] !== "0";
|
|
546550
|
+
const workCapableType = subagentType === "general" || subagentType === "coordinator";
|
|
546551
|
+
const routeToSubprocess = isolation === "worktree" || fullDefault && runInBackground && workCapableType;
|
|
546552
|
+
if (routeToSubprocess) {
|
|
546550
546553
|
this.callbacks.onViewRegister?.(agentId, label);
|
|
546551
546554
|
const spawn35 = this.callbacks.spawnSubprocess({
|
|
546552
546555
|
id: agentId,
|
|
@@ -555351,6 +555354,31 @@ var init_textSanitize = __esm({
|
|
|
555351
555354
|
}
|
|
555352
555355
|
});
|
|
555353
555356
|
|
|
555357
|
+
// packages/orchestrator/dist/permissionRuleset.js
|
|
555358
|
+
function checkDoomLoop(context2) {
|
|
555359
|
+
const history = context2.toolCallHistory;
|
|
555360
|
+
if (!history || history.length < 3)
|
|
555361
|
+
return null;
|
|
555362
|
+
const lastCall = history[history.length - 1];
|
|
555363
|
+
const recent = history.slice(-4);
|
|
555364
|
+
let identicalCount = 1;
|
|
555365
|
+
for (let i2 = history.length - 2; i2 >= Math.max(0, history.length - 4); i2--) {
|
|
555366
|
+
const prev = history[i2];
|
|
555367
|
+
if (prev.tool === lastCall.tool && JSON.stringify(prev.args) === JSON.stringify(lastCall.args)) {
|
|
555368
|
+
identicalCount++;
|
|
555369
|
+
}
|
|
555370
|
+
}
|
|
555371
|
+
if (identicalCount >= 3) {
|
|
555372
|
+
return "ask";
|
|
555373
|
+
}
|
|
555374
|
+
return null;
|
|
555375
|
+
}
|
|
555376
|
+
var init_permissionRuleset = __esm({
|
|
555377
|
+
"packages/orchestrator/dist/permissionRuleset.js"() {
|
|
555378
|
+
"use strict";
|
|
555379
|
+
}
|
|
555380
|
+
});
|
|
555381
|
+
|
|
555354
555382
|
// packages/orchestrator/dist/completionContract.js
|
|
555355
555383
|
function normalizeText(value2, max = 500) {
|
|
555356
555384
|
const text2 = String(value2 ?? "").trim().replace(/\s+/g, " ");
|
|
@@ -565337,6 +565365,7 @@ var init_agenticRunner = __esm({
|
|
|
565337
565365
|
"packages/orchestrator/dist/agenticRunner.js"() {
|
|
565338
565366
|
"use strict";
|
|
565339
565367
|
init_textSanitize();
|
|
565368
|
+
init_permissionRuleset();
|
|
565340
565369
|
init_completionLedger();
|
|
565341
565370
|
init_dist6();
|
|
565342
565371
|
init_ollama_pool();
|
|
@@ -565449,7 +565478,7 @@ var init_agenticRunner = __esm({
|
|
|
565449
565478
|
"repl_exec",
|
|
565450
565479
|
"notebook_edit"
|
|
565451
565480
|
]);
|
|
565452
|
-
AgenticRunner = class {
|
|
565481
|
+
AgenticRunner = class _AgenticRunner {
|
|
565453
565482
|
backend;
|
|
565454
565483
|
tools = /* @__PURE__ */ new Map();
|
|
565455
565484
|
options;
|
|
@@ -567832,10 +567861,12 @@ ${body}`;
|
|
|
567832
567861
|
}
|
|
567833
567862
|
const prior = seen.get(fp);
|
|
567834
567863
|
if (prior) {
|
|
567864
|
+
const priorContent = typeof messages2[prior.idx]?.content === "string" ? messages2[prior.idx].content : "";
|
|
567865
|
+
const priorFailed = ERROR_MARKERS.test(priorContent);
|
|
567835
567866
|
pending2.push({
|
|
567836
567867
|
idx: prior.idx,
|
|
567837
567868
|
reason: "dedupe",
|
|
567838
|
-
replacement: `${DEDUPE_PREFIX} ${scanTurn} — duplicate ${name10}() call]`
|
|
567869
|
+
replacement: priorFailed ? `${DEDUPE_PREFIX} ${scanTurn} — duplicate ${name10}() call; the earlier call FAILED (same error as the retained copy below). Do not retry identically.]` : `${DEDUPE_PREFIX} ${scanTurn} — duplicate ${name10}() call]`
|
|
567839
567870
|
});
|
|
567840
567871
|
seen.set(fp, { turn: scanTurn, idx: resultIdx });
|
|
567841
567872
|
continue;
|
|
@@ -567847,10 +567878,11 @@ ${body}`;
|
|
|
567847
567878
|
if (priorResource && priorResource.idx !== resultIdx) {
|
|
567848
567879
|
const priorContent = typeof messages2[priorResource.idx]?.content === "string" ? messages2[priorResource.idx].content : "";
|
|
567849
567880
|
if (!priorContent.startsWith(PRUNE_PREFIX) && !priorContent.startsWith(DEDUPE_PREFIX) && !priorContent.startsWith(FILE_AGED_PREFIX)) {
|
|
567881
|
+
const priorResFailed = ERROR_MARKERS.test(priorContent);
|
|
567850
567882
|
pending2.push({
|
|
567851
567883
|
idx: priorResource.idx,
|
|
567852
567884
|
reason: "dedupe",
|
|
567853
|
-
replacement: `${DEDUPE_PREFIX} ${scanTurn} — semantic duplicate ${name10}() (same resource: ${rkey})]`
|
|
567885
|
+
replacement: priorResFailed ? `${DEDUPE_PREFIX} ${scanTurn} — semantic duplicate ${name10}() (same resource: ${rkey}); the earlier call FAILED. Do not retry identically.]` : `${DEDUPE_PREFIX} ${scanTurn} — semantic duplicate ${name10}() (same resource: ${rkey})]`
|
|
567854
567886
|
});
|
|
567855
567887
|
}
|
|
567856
567888
|
}
|
|
@@ -570656,6 +570688,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
570656
570688
|
this._worldFacts = { files: /* @__PURE__ */ new Map(), lastTest: {}, lastLists: /* @__PURE__ */ new Map() };
|
|
570657
570689
|
this._argCohorts.clear();
|
|
570658
570690
|
this._adversaryRedundantSignals.clear();
|
|
570691
|
+
this._adversaryRecentFlags.clear();
|
|
570659
570692
|
this._lastTodoWriteTurn = -1;
|
|
570660
570693
|
this._lastTodoReminderTurn = -1;
|
|
570661
570694
|
let pendingConstraintWarnings = [];
|
|
@@ -572789,6 +572822,44 @@ Corrective action: try a different approach first: read relevant files, adjust a
|
|
|
572789
572822
|
timestampMs: Date.now()
|
|
572790
572823
|
});
|
|
572791
572824
|
const _toolLogTailIdx = toolCallLog.length - 1;
|
|
572825
|
+
if (tc.name !== "task_complete") {
|
|
572826
|
+
const doomHistory = toolCallLog.slice(-5).map((e2) => ({ tool: e2.name, args: e2.argsKey }));
|
|
572827
|
+
doomHistory.push({
|
|
572828
|
+
tool: tc.name,
|
|
572829
|
+
args: this._buildExactArgsKey(tc.arguments ?? {})
|
|
572830
|
+
});
|
|
572831
|
+
const doom = checkDoomLoop({
|
|
572832
|
+
permission: tc.name,
|
|
572833
|
+
target: "",
|
|
572834
|
+
toolCallHistory: doomHistory
|
|
572835
|
+
});
|
|
572836
|
+
if (doom === "ask" && cohort && cohort.failure >= 3 && cohort.success === 0) {
|
|
572837
|
+
const stopMsg = `[blocked: doom-loop] '${tc.name}' has been called with identical arguments 3+ times and has failed every time. This exact call was NOT executed. Stop repeating it. Choose ONE: (a) change the arguments or approach, (b) read/inspect to understand why it fails, or (c) if genuinely blocked, call task_complete and state the blocker plainly.`;
|
|
572838
|
+
this.emit({
|
|
572839
|
+
type: "tool_call",
|
|
572840
|
+
toolName: tc.name,
|
|
572841
|
+
toolArgs: tc.arguments,
|
|
572842
|
+
turn,
|
|
572843
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
572844
|
+
});
|
|
572845
|
+
const lastLog = toolCallLog[_toolLogTailIdx];
|
|
572846
|
+
if (lastLog) {
|
|
572847
|
+
lastLog.success = false;
|
|
572848
|
+
lastLog.mutated = false;
|
|
572849
|
+
lastLog.mutatedFiles = [];
|
|
572850
|
+
lastLog.outputPreview = stopMsg.slice(0, 100);
|
|
572851
|
+
}
|
|
572852
|
+
this.emit({
|
|
572853
|
+
type: "tool_result",
|
|
572854
|
+
toolName: tc.name,
|
|
572855
|
+
success: false,
|
|
572856
|
+
content: stopMsg.slice(0, 200),
|
|
572857
|
+
turn,
|
|
572858
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
572859
|
+
});
|
|
572860
|
+
return { tc, output: stopMsg, success: false };
|
|
572861
|
+
}
|
|
572862
|
+
}
|
|
572792
572863
|
if (editFeedbackRequiredBeforeMoreEdits && this._isProjectEditTool(tc.name)) {
|
|
572793
572864
|
this.emit({
|
|
572794
572865
|
type: "tool_call",
|
|
@@ -573970,8 +574041,23 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
573970
574041
|
}
|
|
573971
574042
|
}
|
|
573972
574043
|
const isFileMutation = realFileMutation;
|
|
573973
|
-
if (isFileMutation
|
|
573974
|
-
|
|
574044
|
+
if (isFileMutation) {
|
|
574045
|
+
if (realMutationPaths.length > 0) {
|
|
574046
|
+
for (const mp of realMutationPaths) {
|
|
574047
|
+
if (!mp)
|
|
574048
|
+
continue;
|
|
574049
|
+
for (const key of Array.from(dedupHitCount.keys())) {
|
|
574050
|
+
if (key.includes(mp))
|
|
574051
|
+
dedupHitCount.delete(key);
|
|
574052
|
+
}
|
|
574053
|
+
for (const key of Array.from(recentToolResults.keys())) {
|
|
574054
|
+
if (key.includes(mp))
|
|
574055
|
+
recentToolResults.delete(key);
|
|
574056
|
+
}
|
|
574057
|
+
}
|
|
574058
|
+
} else if (dedupHitCount.size > 0) {
|
|
574059
|
+
dedupHitCount.clear();
|
|
574060
|
+
}
|
|
573975
574061
|
}
|
|
573976
574062
|
if (isFileMutation && recentToolResults.size > 0) {
|
|
573977
574063
|
for (const key of Array.from(recentToolResults.keys())) {
|
|
@@ -574803,7 +574889,6 @@ ${sr.result.output}`;
|
|
|
574803
574889
|
}
|
|
574804
574890
|
if (completed || this._completionIncompleteVerification)
|
|
574805
574891
|
break;
|
|
574806
|
-
this.adversaryObserve(messages2, turn);
|
|
574807
574892
|
const currentRepScore = this.detectRepetition(toolCallLog);
|
|
574808
574893
|
if (currentRepScore > 0.4 && toolCallLog.length >= 4) {
|
|
574809
574894
|
const { repetitionWindow } = this.contextLimits();
|
|
@@ -577896,6 +577981,13 @@ ${trimmedNew}`;
|
|
|
577896
577981
|
/** WO-FIX-C: Tool fingerprints the adversary has flagged as redundant.
|
|
577897
577982
|
* Checked in executeSingle to attach advisory guidance before dispatch. */
|
|
577898
577983
|
_adversaryRedundantSignals = /* @__PURE__ */ new Set();
|
|
577984
|
+
/** Tracks recent adversary detection flags for deduplication and escalation.
|
|
577985
|
+
* Key: "detectionType:fingerprint"
|
|
577986
|
+
* Value: { count: number; lastTurn: number }
|
|
577987
|
+
* When count >= ESCALATE_THRESHOLD, the critique is promoted to system-role. */
|
|
577988
|
+
_adversaryRecentFlags = /* @__PURE__ */ new Map();
|
|
577989
|
+
static ADVERSARY_ESCALATE_THRESHOLD = 3;
|
|
577990
|
+
static ADVERSARY_FLAG_TTL = 5;
|
|
577899
577991
|
/** Reflexion pattern: task-local failure-indexed reflection buffer.
|
|
577900
577992
|
* Generates typed self-reflections on task failure and injects them
|
|
577901
577993
|
* into the next attempt's context for active learning. */
|
|
@@ -577958,6 +578050,23 @@ ${trimmedNew}`;
|
|
|
577958
578050
|
}
|
|
577959
578051
|
while (this._adversaryToolOutcomes.length > 20)
|
|
577960
578052
|
this._adversaryToolOutcomes.shift();
|
|
578053
|
+
for (const [key, val] of this._adversaryRecentFlags) {
|
|
578054
|
+
if (turn - val.lastTurn > _AgenticRunner.ADVERSARY_FLAG_TTL)
|
|
578055
|
+
this._adversaryRecentFlags.delete(key);
|
|
578056
|
+
}
|
|
578057
|
+
const adversaryFlag = (flagKey, messages3) => {
|
|
578058
|
+
const existing = this._adversaryRecentFlags.get(flagKey);
|
|
578059
|
+
if (existing) {
|
|
578060
|
+
existing.count++;
|
|
578061
|
+
existing.lastTurn = turn;
|
|
578062
|
+
if (existing.count >= _AgenticRunner.ADVERSARY_ESCALATE_THRESHOLD) {
|
|
578063
|
+
return "escalate";
|
|
578064
|
+
}
|
|
578065
|
+
return "suppress";
|
|
578066
|
+
}
|
|
578067
|
+
this._adversaryRecentFlags.set(flagKey, { count: 1, lastTurn: turn });
|
|
578068
|
+
return "proceed";
|
|
578069
|
+
};
|
|
577961
578070
|
const emitReaction = (cls, shortText, confidence2, details2) => {
|
|
577962
578071
|
this.emit({
|
|
577963
578072
|
type: "adversary_reaction",
|
|
@@ -577985,9 +578094,9 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
577985
578094
|
const successes = recentOutcomes.filter((o2) => o2.succeeded);
|
|
577986
578095
|
if (successes.length >= 1) {
|
|
577987
578096
|
const successList = successes.map((o2) => `${o2.tool}: ${o2.preview.slice(0, 60)}`).join("; ");
|
|
577988
|
-
|
|
577989
|
-
if (
|
|
577990
|
-
|
|
578097
|
+
const ffFlag = adversaryFlag("false_failure", messages2);
|
|
578098
|
+
if (ffFlag !== "suppress") {
|
|
578099
|
+
const critiqueText = buildAdversaryCritique({
|
|
577991
578100
|
evidence: `Recent tools succeeded: ${successList}.`,
|
|
577992
578101
|
hypothesis: "The main loop is interpreting uncertainty or partial progress as failure and may be about to discard usable evidence.",
|
|
577993
578102
|
correctiveAction: "Use the successful results to advance the task, then verify the next concrete step.",
|
|
@@ -577996,13 +578105,24 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
577996
578105
|
"Read a different targeted file if the successful result exposed a new path or symbol.",
|
|
577997
578106
|
"Complete only if the successful output is sufficient evidence for the user's request."
|
|
577998
578107
|
]
|
|
577999
|
-
})
|
|
578108
|
+
});
|
|
578109
|
+
emitReaction("false_failure", `Claimed failure, but recent tools succeeded (${successes.length})`, 0.9, successList);
|
|
578110
|
+
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
578111
|
+
if (ffFlag === "escalate") {
|
|
578112
|
+
messages2.push({
|
|
578113
|
+
role: "system",
|
|
578114
|
+
content: critiqueText + "\n[ESCALATED: This warning was previously issued without effect.]"
|
|
578115
|
+
});
|
|
578116
|
+
} else {
|
|
578117
|
+
this.pendingUserMessages.push(critiqueText);
|
|
578118
|
+
}
|
|
578119
|
+
}
|
|
578120
|
+
this.emit({
|
|
578121
|
+
type: "status",
|
|
578122
|
+
content: `\x1B[38;5;178m⚠ Corrected false failure claim (${successes.length} tools succeeded)\x1B[0m`,
|
|
578123
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
578124
|
+
});
|
|
578000
578125
|
}
|
|
578001
|
-
this.emit({
|
|
578002
|
-
type: "status",
|
|
578003
|
-
content: `\x1B[38;5;178m⚠ Corrected false failure claim (${successes.length} tools succeeded)\x1B[0m`,
|
|
578004
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
578005
|
-
});
|
|
578006
578126
|
}
|
|
578007
578127
|
}
|
|
578008
578128
|
}
|
|
@@ -578015,9 +578135,9 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
578015
578135
|
const successes = recentOutcomes.filter((o2) => o2.succeeded);
|
|
578016
578136
|
if (failures.length > 0 && successes.length === 0) {
|
|
578017
578137
|
const failList = failures.map((o2) => `${o2.tool}: ${o2.preview.slice(0, 60)}`).join("; ");
|
|
578018
|
-
|
|
578019
|
-
if (
|
|
578020
|
-
|
|
578138
|
+
const fsFlag = adversaryFlag("false_success", messages2);
|
|
578139
|
+
if (fsFlag !== "suppress") {
|
|
578140
|
+
const critiqueText = buildAdversaryCritique({
|
|
578021
578141
|
evidence: `Recent tools show errors (${failures.length}): ${failList}.`,
|
|
578022
578142
|
hypothesis: "The main loop is prematurely compressing intent into success language before the verifier produced evidence.",
|
|
578023
578143
|
correctiveAction: "Inspect the failed output, identify the implicated path/symbol/command, and run one focused corrective step before claiming success.",
|
|
@@ -578026,7 +578146,18 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
578026
578146
|
"Patch the implicated code or configuration.",
|
|
578027
578147
|
"Run the same verifier only after a state-changing fix."
|
|
578028
578148
|
]
|
|
578029
|
-
})
|
|
578149
|
+
});
|
|
578150
|
+
emitReaction("false_success", `Claimed success, but recent tools failed (${failures.length})`, 0.9, failList);
|
|
578151
|
+
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
578152
|
+
if (fsFlag === "escalate") {
|
|
578153
|
+
messages2.push({
|
|
578154
|
+
role: "system",
|
|
578155
|
+
content: critiqueText + "\n[ESCALATED: This warning was previously issued without effect.]"
|
|
578156
|
+
});
|
|
578157
|
+
} else {
|
|
578158
|
+
this.pendingUserMessages.push(critiqueText);
|
|
578159
|
+
}
|
|
578160
|
+
}
|
|
578030
578161
|
}
|
|
578031
578162
|
}
|
|
578032
578163
|
}
|
|
@@ -578048,9 +578179,9 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
578048
578179
|
const prior = this._adversaryToolOutcomes.find((o2) => o2.succeeded && o2.tool === name10 && o2.fingerprint === fingerprint && o2.turn < turn);
|
|
578049
578180
|
if (prior) {
|
|
578050
578181
|
this._adversaryRedundantSignals.add(fingerprint);
|
|
578051
|
-
|
|
578052
|
-
if (
|
|
578053
|
-
|
|
578182
|
+
const raFlag = adversaryFlag(`redundant_action:${fingerprint}`, messages2);
|
|
578183
|
+
if (raFlag !== "suppress") {
|
|
578184
|
+
const critiqueText = buildAdversaryCritique({
|
|
578054
578185
|
evidence: `${name10} already succeeded on turn ${prior.turn} with exact arguments (${argsKey.slice(0, 120)}). Prior preview: ${prior.preview}`,
|
|
578055
578186
|
hypothesis: "The main loop may have lost track of previously observed evidence because of context pressure, path confusion, or repeated discovery.",
|
|
578056
578187
|
correctiveAction: "Let this duplicate run execute if needed, but treat the prior result as evidence and pivot afterward unless state has changed.",
|
|
@@ -578059,13 +578190,24 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
578059
578190
|
"Read a different specific file or selector if the current evidence is insufficient.",
|
|
578060
578191
|
"Repeat exact arguments only when filesystem, browser, or page state changed."
|
|
578061
578192
|
]
|
|
578062
|
-
})
|
|
578193
|
+
});
|
|
578194
|
+
emitReaction("redundant_action", `Already ran ${name10} successfully on turn ${prior.turn}`, 0.8, prior.preview);
|
|
578195
|
+
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
578196
|
+
if (raFlag === "escalate") {
|
|
578197
|
+
messages2.push({
|
|
578198
|
+
role: "system",
|
|
578199
|
+
content: critiqueText + "\n[ESCALATED: This redundant-action warning was issued 3+ times as a user message without effect.]"
|
|
578200
|
+
});
|
|
578201
|
+
} else {
|
|
578202
|
+
this.pendingUserMessages.push(critiqueText);
|
|
578203
|
+
}
|
|
578204
|
+
}
|
|
578205
|
+
this.emit({
|
|
578206
|
+
type: "status",
|
|
578207
|
+
content: `\x1B[38;5;178m⚠ Adversary noted redundant ${name10} call (succeeded on turn ${prior.turn}); action remains allowed\x1B[0m`,
|
|
578208
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
578209
|
+
});
|
|
578063
578210
|
}
|
|
578064
|
-
this.emit({
|
|
578065
|
-
type: "status",
|
|
578066
|
-
content: `\x1B[38;5;178m⚠ Adversary noted redundant ${name10} call (succeeded on turn ${prior.turn}); action remains allowed\x1B[0m`,
|
|
578067
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
578068
|
-
});
|
|
578069
578211
|
break;
|
|
578070
578212
|
}
|
|
578071
578213
|
}
|
|
@@ -578083,9 +578225,9 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
578083
578225
|
}
|
|
578084
578226
|
}
|
|
578085
578227
|
if (consecutiveShortResults >= 3) {
|
|
578086
|
-
|
|
578087
|
-
if (
|
|
578088
|
-
|
|
578228
|
+
const itFlag = adversaryFlag("idle_think", messages2);
|
|
578229
|
+
if (itFlag !== "suppress") {
|
|
578230
|
+
const critiqueText = buildAdversaryCritique({
|
|
578089
578231
|
evidence: `${consecutiveShortResults} consecutive output-like calls occurred without an input-like observation.`,
|
|
578090
578232
|
hypothesis: "The loop may be acting from stale state instead of re-observing the environment.",
|
|
578091
578233
|
correctiveAction: "Take one input/observation step before another output step.",
|
|
@@ -578094,13 +578236,24 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
578094
578236
|
"Read the current UI/page state before clicking or typing again.",
|
|
578095
578237
|
"If the task is already complete, finish with the concrete evidence already observed."
|
|
578096
578238
|
]
|
|
578097
|
-
})
|
|
578239
|
+
});
|
|
578240
|
+
emitReaction("idle_think", `Consecutive output without input: ${consecutiveShortResults}`, 0.7);
|
|
578241
|
+
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
578242
|
+
if (itFlag === "escalate") {
|
|
578243
|
+
messages2.push({
|
|
578244
|
+
role: "system",
|
|
578245
|
+
content: critiqueText + "\n[ESCALATED: This warning was previously issued without effect.]"
|
|
578246
|
+
});
|
|
578247
|
+
} else {
|
|
578248
|
+
this.pendingUserMessages.push(critiqueText);
|
|
578249
|
+
}
|
|
578250
|
+
}
|
|
578251
|
+
this.emit({
|
|
578252
|
+
type: "status",
|
|
578253
|
+
content: `\x1B[38;5;178m⚠ Adversary flagged runaway-output risk (${consecutiveShortResults} consecutive sends without receive); action remains allowed\x1B[0m`,
|
|
578254
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
578255
|
+
});
|
|
578098
578256
|
}
|
|
578099
|
-
this.emit({
|
|
578100
|
-
type: "status",
|
|
578101
|
-
content: `\x1B[38;5;178m⚠ Adversary flagged runaway-output risk (${consecutiveShortResults} consecutive sends without receive); action remains allowed\x1B[0m`,
|
|
578102
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
578103
|
-
});
|
|
578104
578257
|
}
|
|
578105
578258
|
}
|
|
578106
578259
|
}
|
|
@@ -602267,7 +602420,7 @@ var init_call_agent = __esm({
|
|
|
602267
602420
|
}
|
|
602268
602421
|
/** Initialize the runner with appropriate tools for the access tier */
|
|
602269
602422
|
async init() {
|
|
602270
|
-
const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey);
|
|
602423
|
+
const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey, false);
|
|
602271
602424
|
this.backend = backend;
|
|
602272
602425
|
const feed = getActivityFeed();
|
|
602273
602426
|
const systemPrompt = this.buildSystemPrompt();
|
|
@@ -608597,6 +608750,8 @@ ${CONTENT_BG_SEQ}`);
|
|
|
608597
608750
|
this._trueStdoutWrite.call(process.stdout, `\x1B[${scrollEnd};1H`);
|
|
608598
608751
|
this.renderFooterAndPositionInput();
|
|
608599
608752
|
this._trueStdoutWrite.call(process.stdout, `\x1B[${scrollEnd};1H`);
|
|
608753
|
+
this._trueStdoutWrite.call(process.stdout, `
|
|
608754
|
+
`);
|
|
608600
608755
|
this.termWrite("\x1B[?2026l");
|
|
608601
608756
|
this._bufferContent = true;
|
|
608602
608757
|
}
|
|
@@ -608966,7 +609121,18 @@ ${CONTENT_BG_SEQ}`);
|
|
|
608966
609121
|
const text2 = stripped.join("\n");
|
|
608967
609122
|
if (text2.length === 0) return;
|
|
608968
609123
|
const ok3 = copyText(text2);
|
|
608969
|
-
|
|
609124
|
+
const pos = this.rowPositions(termRows());
|
|
609125
|
+
const writer = this._origWrite ?? process.stdout.write.bind(process.stdout);
|
|
609126
|
+
if (ok3) {
|
|
609127
|
+
if (pos.metricsRow > 0) {
|
|
609128
|
+
writer(
|
|
609129
|
+
`\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;${TEXT_PRIMARY}m ✓ Copied session to clipboard\x1B[0m`
|
|
609130
|
+
);
|
|
609131
|
+
}
|
|
609132
|
+
setTimeout(() => {
|
|
609133
|
+
if (this.active) this.renderFooterAndPositionInput();
|
|
609134
|
+
}, 1200);
|
|
609135
|
+
} else {
|
|
608970
609136
|
try {
|
|
608971
609137
|
const fs11 = __require("fs");
|
|
608972
609138
|
const os9 = __require("os");
|
|
@@ -608975,16 +609141,21 @@ ${CONTENT_BG_SEQ}`);
|
|
|
608975
609141
|
"omnius-session-copy.txt"
|
|
608976
609142
|
);
|
|
608977
609143
|
fs11.writeFileSync(tmpPath, text2, "utf-8");
|
|
608978
|
-
|
|
608979
|
-
|
|
608980
|
-
`
|
|
608981
|
-
|
|
609144
|
+
if (pos.metricsRow > 0) {
|
|
609145
|
+
writer(
|
|
609146
|
+
`\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;208mSession saved to temp file\x1B[0m`
|
|
609147
|
+
);
|
|
609148
|
+
}
|
|
608982
609149
|
} catch {
|
|
608983
|
-
|
|
608984
|
-
|
|
608985
|
-
`
|
|
608986
|
-
|
|
609150
|
+
if (pos.metricsRow > 0) {
|
|
609151
|
+
writer(
|
|
609152
|
+
`\x1B[${pos.metricsRow};1H\x1B[2K\x1B[38;5;196mFailed to copy session\x1B[0m`
|
|
609153
|
+
);
|
|
609154
|
+
}
|
|
608987
609155
|
}
|
|
609156
|
+
setTimeout(() => {
|
|
609157
|
+
if (this.active) this.renderFooterAndPositionInput();
|
|
609158
|
+
}, 3e3);
|
|
608988
609159
|
}
|
|
608989
609160
|
}
|
|
608990
609161
|
/**
|
|
@@ -704126,6 +704297,7 @@ ${entry.fullContent}`
|
|
|
704126
704297
|
if (!liveShellBlock) return;
|
|
704127
704298
|
liveShellBlock.repaintTimer = null;
|
|
704128
704299
|
if (statusBar?.isActive) statusBar.refreshDisplay();
|
|
704300
|
+
if (liveShellBlock.state.status === "running") scheduleLiveShellRepaint();
|
|
704129
704301
|
}, 33);
|
|
704130
704302
|
liveShellBlock.repaintTimer.unref?.();
|
|
704131
704303
|
};
|
|
@@ -704227,6 +704399,7 @@ ${entry.fullContent}`
|
|
|
704227
704399
|
(width) => buildShellLiveBlockLines(state, width)
|
|
704228
704400
|
);
|
|
704229
704401
|
liveShellStatusBar.appendDynamicBlock(id);
|
|
704402
|
+
scheduleLiveShellRepaint();
|
|
704230
704403
|
}
|
|
704231
704404
|
});
|
|
704232
704405
|
}
|
|
@@ -705558,7 +705731,13 @@ Review its full output via sub_agent(action='output', id='${id}')`
|
|
|
705558
705731
|
backend = new OllamaAgenticBackend(
|
|
705559
705732
|
config.backendUrl,
|
|
705560
705733
|
opts.model,
|
|
705561
|
-
config.apiKey
|
|
705734
|
+
config.apiKey,
|
|
705735
|
+
// Sub-agents: force thinking OFF explicitly. Thinking models
|
|
705736
|
+
// interleave <think> blocks that corrupt tool-call parsing for
|
|
705737
|
+
// Qwen/Ollama. Relying on the constructor default is fragile
|
|
705738
|
+
// (breaks if OMNIUS_ENABLE_THINKING=1 is inherited); pass false
|
|
705739
|
+
// so sub-agent tool loops are always clean.
|
|
705740
|
+
false
|
|
705562
705741
|
);
|
|
705563
705742
|
}
|
|
705564
705743
|
const subTier = getModelTier(opts.model);
|
|
@@ -705595,6 +705774,10 @@ Review its full output via sub_agent(action='output', id='${id}')`
|
|
|
705595
705774
|
`Sub-agent ${subAgentId}`,
|
|
705596
705775
|
"sub"
|
|
705597
705776
|
);
|
|
705777
|
+
subRunner.onEvent((event) => {
|
|
705778
|
+
const line = formatSubAgentEventForView(event);
|
|
705779
|
+
if (line) statusBar.writeToAgentView(subAgentId, line);
|
|
705780
|
+
});
|
|
705598
705781
|
subRunner.registerTool(
|
|
705599
705782
|
createTaskCompleteTool(subTier, repoRoot, true)
|
|
705600
705783
|
);
|
|
@@ -705637,11 +705820,21 @@ ${result.summary}`
|
|
|
705637
705820
|
};
|
|
705638
705821
|
},
|
|
705639
705822
|
spawnSubprocess: (opts) => {
|
|
705640
|
-
const entry = spawnFullSubAgent(
|
|
705641
|
-
|
|
705642
|
-
|
|
705643
|
-
|
|
705644
|
-
|
|
705823
|
+
const entry = spawnFullSubAgent(
|
|
705824
|
+
opts.task,
|
|
705825
|
+
{
|
|
705826
|
+
model: opts.model,
|
|
705827
|
+
backendUrl: config.backendUrl,
|
|
705828
|
+
workingDir: opts.workingDir
|
|
705829
|
+
},
|
|
705830
|
+
// Stream the full sub-agent's stdout into its toolbar view so the
|
|
705831
|
+
// clickable tab shows live output instead of staying empty.
|
|
705832
|
+
(text2) => statusBar.writeToAgentView(opts.id, text2),
|
|
705833
|
+
(id, exitCode) => statusBar.updateAgentViewStatus(
|
|
705834
|
+
opts.id,
|
|
705835
|
+
exitCode === 0 ? "completed" : "failed"
|
|
705836
|
+
)
|
|
705837
|
+
);
|
|
705645
705838
|
return { id: entry.id, pid: entry.pid ?? 0 };
|
|
705646
705839
|
},
|
|
705647
705840
|
trackTask: (id, promise) => {
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Delay Fix Review — Commits Since Delay Analysis
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-10
|
|
4
|
+
**Reference:** `/docs/operations/delay-analysis.md` (15 delay sources documented)
|
|
5
|
+
|
|
6
|
+
## Commit Map
|
|
7
|
+
|
|
8
|
+
| Commit | Message | Files | Insertions | Date |
|
|
9
|
+
|--------|---------|-------|------------|------|
|
|
10
|
+
| b24bc55d | slots | 5 | +80/-18 | Jun 9 22:04 |
|
|
11
|
+
| cb043dce | interactive | 11 | +865/-259 | Jun 9 21:45 |
|
|
12
|
+
| ca1da293 | error catch | 12 | +389/-144 | Jun 9 10:26 |
|
|
13
|
+
| 1fcdd81e | progress | 10 | +724/-19 | Jun 8 22:46 |
|
|
14
|
+
|
|
15
|
+
Total: 38 files changed, ~2,058 insertions, ~440 deletions across ~4 hours.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Delay Source Mapping — What Got Fixed
|
|
20
|
+
|
|
21
|
+
### 1. `stableValueKey` — O(n) JSON.stringify on large arrays/objects (Delay #1)
|
|
22
|
+
**Status: FIXED** (commit b24bc55d)
|
|
23
|
+
|
|
24
|
+
Evidence from `git show b24bc55d -- packages/orchestrator/src/streaming-executor.ts`:
|
|
25
|
+
```diff
|
|
26
|
+
- if (Array.isArray(value)) return `[${value.map(stableValueKey).join(",")}]`;
|
|
27
|
+
+ if (Array.isArray(value)) {
|
|
28
|
+
+ if (value.length > 256) return `[${value.length}items]`;
|
|
29
|
+
+ return `[${value.map(stableValueKey).join(",")}]`;
|
|
30
|
+
+ }
|
|
31
|
+
+ const raw = JSON.stringify(value);
|
|
32
|
+
+ if (raw.length > 10_240) {
|
|
33
|
+
+ let hash = 5381;
|
|
34
|
+
+ for (let i = 0; i < raw.length; i++)
|
|
35
|
+
+ hash = ((hash << 5) + hash + raw.charCodeAt(i)) | 0;
|
|
36
|
+
+ return `{size:${raw.length},hash:${Math.abs(hash).toString(36)}}`;
|
|
37
|
+
+ }
|
|
38
|
+
```
|
|
39
|
+
- Array length cap at 256 items prevents O(n) traversal on large arrays
|
|
40
|
+
- Object size cap at 10KB prevents O(n) stringify on large objects
|
|
41
|
+
- Fallback to djb2 hash for oversized objects
|
|
42
|
+
- **Impact:** High — this was a core loop bottleneck in tool deduplication
|
|
43
|
+
|
|
44
|
+
### 2. Tool batching / deduplication (Delay #2)
|
|
45
|
+
**Status: PARTIALLY ADDRESSED** (commit b24bc55d)
|
|
46
|
+
|
|
47
|
+
`tool-batching.ts` changed (+26/-18 in b24bc55d). The `stableValueKey` fix above directly addresses the dedup cost. Need to verify if batching window logic was also touched.
|
|
48
|
+
|
|
49
|
+
### 3. Ollama pool / GPU detection (Delay #3, #4)
|
|
50
|
+
**Status: MAJOR REWRITE** (commits cb043dce + b24bc55d)
|
|
51
|
+
|
|
52
|
+
- `ollama-pool.ts`: +452/-259 in cb043dce, +35/-1 in b24bc55d
|
|
53
|
+
- This is the single largest change — a full rewrite of the Ollama pool
|
|
54
|
+
- The "slots" commit (b24bc55d) specifically touched ollama-pool.ts with 35 insertions
|
|
55
|
+
- **Impact:** Very high — GPU detection and model loading are on the critical path
|
|
56
|
+
|
|
57
|
+
### 4. Cascade backend / parallel inference (Delay #5)
|
|
58
|
+
**Status: CHANGED** (commit cb043dce)
|
|
59
|
+
|
|
60
|
+
`cascadeBackend.ts` changed +118/-lines in cb043dce. The "interactive" commit touched this file. Need to verify if parallel backend selection was improved.
|
|
61
|
+
|
|
62
|
+
### 5. Steering intake timeout (Delay #6)
|
|
63
|
+
**Status: CHANGED** (commit cb043dce)
|
|
64
|
+
|
|
65
|
+
`steeringIntake.ts` changed +79/-lines in cb043dce. The "interactive" commit touched this. Need to verify timeout values.
|
|
66
|
+
|
|
67
|
+
### 6. Verifier runner timeout (Delay #7)
|
|
68
|
+
**Status: CHANGED** (commit b24bc55d)
|
|
69
|
+
|
|
70
|
+
`verifierRunner.ts` changed +12/-lines in b24bc55d. The "slots" commit touched this.
|
|
71
|
+
|
|
72
|
+
### 7. Preflight snapshot (Delay #8)
|
|
73
|
+
**Status: CHANGED** (commit cb043dce)
|
|
74
|
+
|
|
75
|
+
`preflightSnapshot.ts` changed +44/-lines in cb043dce.
|
|
76
|
+
|
|
77
|
+
### 8. Agentic runner error handling (Delay #9)
|
|
78
|
+
**Status: FIXED** (commits ca1da293 + 1fcdd81e)
|
|
79
|
+
|
|
80
|
+
- ca1da293: agenticRunner.ts +102/-lines (error catch)
|
|
81
|
+
- 1fcdd81e: agenticRunner.ts +28/-lines (progress)
|
|
82
|
+
- Total: ~130 lines of error handling improvements
|
|
83
|
+
|
|
84
|
+
### 9. Prompt caching (Delay #10)
|
|
85
|
+
**Status: ADDED** (commit 1fcdd81e)
|
|
86
|
+
|
|
87
|
+
`prompt-cache.ts` added (+30 lines) in commit 1fcdd81e "progress". New file for prompt caching.
|
|
88
|
+
|
|
89
|
+
### 10. Context references (Delay #11)
|
|
90
|
+
**Status: IMPROVED** (commit 1fcdd81e)
|
|
91
|
+
|
|
92
|
+
`context-references.ts` changed +55/-lines in 1fcdd81e.
|
|
93
|
+
|
|
94
|
+
### 11. TUI render / text wrapping (Delay #12)
|
|
95
|
+
**Status: FIXED** (commits cb043dce + b24bc55d)
|
|
96
|
+
|
|
97
|
+
- cb043dce: render.ts +44/-lines
|
|
98
|
+
- b24bc55d: render.ts +13/-lines
|
|
99
|
+
- Both commits touched render.ts for text rendering improvements
|
|
100
|
+
|
|
101
|
+
### 12. Interactive mode (Delay #13)
|
|
102
|
+
**Status: ADDED** (commit cb043dce)
|
|
103
|
+
|
|
104
|
+
New file `packages/cli/src/tui/interactive.ts` (+39 lines) in cb043dce.
|
|
105
|
+
|
|
106
|
+
### 13. Integration tests (Delay #14)
|
|
107
|
+
**Status: ADDED** (commits ca1da293 + 1fcdd81e)
|
|
108
|
+
|
|
109
|
+
- ca1da293: 4 new test files
|
|
110
|
+
- 1fcdd81e: 2 new test files (agenticRunner.test.ts, prompt-caching.test.ts)
|
|
111
|
+
|
|
112
|
+
### 14. Publish artifacts (Delay #15)
|
|
113
|
+
**Status: UNCHANGED** (no delay-related changes)
|
|
114
|
+
|
|
115
|
+
Only `publish/npm-shrinkwrap.json` and `publish/package.json` changed in working tree (uncommitted).
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Summary Assessment
|
|
120
|
+
|
|
121
|
+
### Fixed / Addressed (8/15 delay sources)
|
|
122
|
+
1. **stableValueKey** — fully fixed with array/object size caps
|
|
123
|
+
2. **Tool deduplication** — addressed via stableValueKey fix
|
|
124
|
+
3. **Ollama pool** — major rewrite (452+35 lines)
|
|
125
|
+
4. **Agentic runner errors** — ~130 lines of error handling
|
|
126
|
+
5. **Prompt caching** — new file added
|
|
127
|
+
6. **Context references** — improved (+55 lines)
|
|
128
|
+
7. **TUI render** — text wrapping fixed
|
|
129
|
+
8. **Interactive mode** — new feature added
|
|
130
|
+
|
|
131
|
+
### Changed but Need Verification (4/15)
|
|
132
|
+
9. **Cascade backend** — +118 lines, need to verify parallel improvement
|
|
133
|
+
10. **Steering intake** — +79 lines, need to verify timeout values
|
|
134
|
+
11. **Verifier runner** — +12 lines, need to verify timeout values
|
|
135
|
+
12. **Preflight snapshot** — +44 lines, need to verify probe timeout
|
|
136
|
+
|
|
137
|
+
### Not Addressed (3/15)
|
|
138
|
+
13. **Publish artifacts** — no delay-related changes
|
|
139
|
+
14. **Integration tests** — added but not a delay fix per se
|
|
140
|
+
15. **Working tree state** — only publish files changed (uncommitted)
|
|
141
|
+
|
|
142
|
+
### Overall Assessment
|
|
143
|
+
- **~53% of delay sources addressed** (8/15 fixed, 4/15 changed pending verification)
|
|
144
|
+
- The "slots" commit (b24bc55d) is the most recent and focused on core loop fixes
|
|
145
|
+
- The "interactive" commit (cb043dce) is the largest and touched the most files
|
|
146
|
+
- **Key gap:** Need to verify the actual timeout values in cascadeBackend.ts, steeringIntake.ts, and verifierRunner.ts to confirm the changes actually reduce delays
|
|
147
|
+
- **Key gap:** The working tree has 2 uncommitted changes in publish/ — need to check if these are relevant
|
|
148
|
+
|
|
149
|
+
### Recommended Next Steps
|
|
150
|
+
1. Verify timeout values in cascadeBackend.ts, steeringIntake.ts, verifierRunner.ts
|
|
151
|
+
2. Check if ollama-pool.ts rewrite includes GPU detection improvements
|
|
152
|
+
3. Verify the working tree changes in publish/ are intentional
|
|
153
|
+
4. Run the build to ensure all changes compile cleanly
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.271",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.271",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED