omnius 1.0.454 → 1.0.456
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 +332 -219
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14238,6 +14238,66 @@ function findMatchOffsets(haystack, needle) {
|
|
|
14238
14238
|
function replaceAllOccurrences(haystack, needle, replacement) {
|
|
14239
14239
|
return haystack.split(needle).join(replacement);
|
|
14240
14240
|
}
|
|
14241
|
+
function buildMissingOldStringLlmContent(input) {
|
|
14242
|
+
const lines = [
|
|
14243
|
+
"[FILE_EDIT_OLD_STRING_NOT_FOUND]",
|
|
14244
|
+
`path=${input.path}`,
|
|
14245
|
+
"The attempted old_string was absent from the current file.",
|
|
14246
|
+
"Do not copy diagnostic gutters into old_string. Ignore line numbers, leading '>' markers, and the '|' separator.",
|
|
14247
|
+
"",
|
|
14248
|
+
"attempted_old_string:",
|
|
14249
|
+
fencedText(input.attemptedOldString)
|
|
14250
|
+
];
|
|
14251
|
+
if (input.snippetContent) {
|
|
14252
|
+
const range = input.snippetStartLine && input.snippetEndLine && input.totalLines ? `lines ${input.snippetStartLine}-${input.snippetEndLine} of ${input.totalLines}` : "closest current text";
|
|
14253
|
+
lines.push("", `copyable_current_text_without_gutters (${range}):`, fencedText(stripDiagnosticGutters(input.snippetContent)), "", "Next action: build a new file_edit old_string only from the copyable_current_text_without_gutters block, or file_read the target if more context is needed.");
|
|
14254
|
+
} else {
|
|
14255
|
+
lines.push("", "Next action: file_read the target, then build old_string from exact current file content.");
|
|
14256
|
+
}
|
|
14257
|
+
lines.push("", "Do not use shell text-rewrite commands as a workaround for this edit failure; keep the change tracked through file_edit, batch_edit, file_patch, or file_write.");
|
|
14258
|
+
if (input.newString.length > 0) {
|
|
14259
|
+
lines.push("", "desired_new_string:", fencedText(input.newString));
|
|
14260
|
+
}
|
|
14261
|
+
return lines.join("\n");
|
|
14262
|
+
}
|
|
14263
|
+
function buildAmbiguousOldStringLlmContent(input) {
|
|
14264
|
+
const replaceAllArgs = {
|
|
14265
|
+
path: input.path,
|
|
14266
|
+
old_string: input.oldString,
|
|
14267
|
+
new_string: input.newString,
|
|
14268
|
+
replace_all: true
|
|
14269
|
+
};
|
|
14270
|
+
return [
|
|
14271
|
+
"[FILE_EDIT_AMBIGUOUS_OLD_STRING]",
|
|
14272
|
+
`path=${input.path}`,
|
|
14273
|
+
`old_string matched ${input.occurrences} locations at lines ${input.matchLines.join(", ")}.`,
|
|
14274
|
+
"Do not retry the same old_string without either replace_all=true or additional unique surrounding context.",
|
|
14275
|
+
"Do not copy diagnostic gutters into old_string. Ignore line numbers, leading '>' markers, and the '|' separator.",
|
|
14276
|
+
"",
|
|
14277
|
+
"valid_next_action_replace_all_if_every_match_should_change_identically:",
|
|
14278
|
+
fencedJson(replaceAllArgs),
|
|
14279
|
+
"",
|
|
14280
|
+
"valid_next_action_single_location:",
|
|
14281
|
+
"Use file_edit with an old_string that includes unique surrounding current file text from exactly one match below.",
|
|
14282
|
+
"",
|
|
14283
|
+
"copyable_match_contexts_without_gutters:",
|
|
14284
|
+
fencedText(stripDiagnosticGutters(input.snippets).trim()),
|
|
14285
|
+
"",
|
|
14286
|
+
"Do not use shell text-rewrite commands as a workaround for this ambiguity; keep the change tracked through file_edit, batch_edit, file_patch, or file_write."
|
|
14287
|
+
].join("\n");
|
|
14288
|
+
}
|
|
14289
|
+
function stripDiagnosticGutters(text2) {
|
|
14290
|
+
return text2.split("\n").map((line) => {
|
|
14291
|
+
const match = line.match(/^[ >]\s*\d+\s\|\s?(.*)$/);
|
|
14292
|
+
return match ? match[1] ?? "" : line;
|
|
14293
|
+
}).join("\n");
|
|
14294
|
+
}
|
|
14295
|
+
function fencedText(value2) {
|
|
14296
|
+
return ["```text", value2, "```"].join("\n");
|
|
14297
|
+
}
|
|
14298
|
+
function fencedJson(value2) {
|
|
14299
|
+
return ["```json", JSON.stringify(value2, null, 2), "```"].join("\n");
|
|
14300
|
+
}
|
|
14241
14301
|
var FileEditTool;
|
|
14242
14302
|
var init_file_edit = __esm({
|
|
14243
14303
|
"packages/execution/dist/tools/file-edit.js"() {
|
|
@@ -14394,6 +14454,15 @@ Use the EXACT current content above to construct a working old_string. Do not re
|
|
|
14394
14454
|
success: false,
|
|
14395
14455
|
output: "",
|
|
14396
14456
|
error: errorMsg,
|
|
14457
|
+
llmContent: buildMissingOldStringLlmContent({
|
|
14458
|
+
path: filePath,
|
|
14459
|
+
attemptedOldString: oldString,
|
|
14460
|
+
newString,
|
|
14461
|
+
snippetContent: snippet?.content ?? null,
|
|
14462
|
+
snippetStartLine: snippet?.startLine ?? null,
|
|
14463
|
+
snippetEndLine: snippet?.endLine ?? null,
|
|
14464
|
+
totalLines: snippet?.totalLines ?? null
|
|
14465
|
+
}),
|
|
14397
14466
|
durationMs: performance.now() - start2,
|
|
14398
14467
|
mutated: false,
|
|
14399
14468
|
mutatedFiles: [],
|
|
@@ -14417,6 +14486,14 @@ ${s2.content}`;
|
|
|
14417
14486
|
${snippets}
|
|
14418
14487
|
|
|
14419
14488
|
Add UNIQUE surrounding context (a function name, distinctive comment, or unique line above/below) to disambiguate. Or set replace_all=true if you want all ${occurrences} occurrences replaced identically.`,
|
|
14489
|
+
llmContent: buildAmbiguousOldStringLlmContent({
|
|
14490
|
+
path: filePath,
|
|
14491
|
+
oldString,
|
|
14492
|
+
newString,
|
|
14493
|
+
occurrences,
|
|
14494
|
+
matchLines,
|
|
14495
|
+
snippets
|
|
14496
|
+
}),
|
|
14420
14497
|
durationMs: performance.now() - start2,
|
|
14421
14498
|
mutated: false,
|
|
14422
14499
|
mutatedFiles: [],
|
|
@@ -566026,12 +566103,12 @@ function buildCriticGuidanceMessage(call, hits, opts = {}) {
|
|
|
566026
566103
|
const cached = opts.cachedResult ? `
|
|
566027
566104
|
Prior evidence preview:
|
|
566028
566105
|
${opts.cachedResult.slice(0, 700)}` : "";
|
|
566029
|
-
const source = opts.adversaryFlag ? "The
|
|
566030
|
-
return `[
|
|
566106
|
+
const source = opts.adversaryFlag ? "The runtime recognized this exact tool call as already observed earlier." : `This is exact repeat #${hits} for the same ${call.tool} arguments.`;
|
|
566107
|
+
return `[RUNTIME EVIDENCE CACHE — non-blocking]
|
|
566031
566108
|
Observation: ${source}
|
|
566032
566109
|
Call: ${call.tool}(${argPreview})
|
|
566033
|
-
|
|
566034
|
-
|
|
566110
|
+
State: exact prior evidence exists for these arguments in the current state version.
|
|
566111
|
+
Next action contract: let this result inform the next step once, then pivot to a concrete action.
|
|
566035
566112
|
Suggested next actions: edit/write the implicated file, run verification, read a different specific file, or complete with evidence. Prefer not to repeat this exact call again unless the filesystem, browser, or page state changed.${cached}`;
|
|
566036
566113
|
}
|
|
566037
566114
|
function buildCachedResultEnvelope(result) {
|
|
@@ -570813,7 +570890,7 @@ ${fileLines}`);
|
|
|
570813
570890
|
const counts = { ok: 0, failed: 0, blocked: 0 };
|
|
570814
570891
|
for (const ev of events) {
|
|
570815
570892
|
const preview = ev.outputPreview ?? "";
|
|
570816
|
-
if (preview.includes("[FOCUS SUPERVISOR BLOCK]") || preview.includes("[STOP RE-RUNNING") || preview.includes("[REPEAT GATE")) {
|
|
570893
|
+
if (preview.includes("[FOCUS SUPERVISOR BLOCK]") || preview.includes("[STOP RE-RUNNING") || preview.includes("[CACHED VERIFIER FAILURE") || preview.includes("[REPEAT GATE")) {
|
|
570817
570894
|
counts.blocked++;
|
|
570818
570895
|
} else if (ev.success === false) {
|
|
570819
570896
|
counts.failed++;
|
|
@@ -573775,6 +573852,10 @@ function adversarySystemPrompt() {
|
|
|
573775
573852
|
].join("\n");
|
|
573776
573853
|
}
|
|
573777
573854
|
function buildObservationPrompt(obs, recentLedger) {
|
|
573855
|
+
const stateDigest = obs.stateDigest ? `
|
|
573856
|
+
Runner world/progress digest:
|
|
573857
|
+
${obs.stateDigest.slice(0, 1800)}
|
|
573858
|
+
` : "";
|
|
573778
573859
|
const outcomes = obs.recentToolOutcomes.slice(-8).map((o2) => {
|
|
573779
573860
|
const target = o2.path ? ` path=${o2.path}` : "";
|
|
573780
573861
|
const evidence = o2.evidence ? ` | evidence: ${o2.evidence.slice(0, 220)}` : "";
|
|
@@ -573788,6 +573869,8 @@ function buildObservationPrompt(obs, recentLedger) {
|
|
|
573788
573869
|
`This is a loop. Reason about WHY — for THIS specific call, not generically.`,
|
|
573789
573870
|
ls2.alreadyHave ? `Evidence the agent ALREADY obtained from a prior identical call:
|
|
573790
573871
|
${ls2.alreadyHave.slice(0, 900)}` : `(No cached result available for the repeated call.)`,
|
|
573872
|
+
"",
|
|
573873
|
+
stateDigest.trim(),
|
|
573791
573874
|
"",
|
|
573792
573875
|
"Agent's latest message:",
|
|
573793
573876
|
obs.assistantText.slice(0, 1200) || "(empty)",
|
|
@@ -573809,6 +573892,8 @@ ${ls2.alreadyHave.slice(0, 900)}` : `(No cached result available for the repeate
|
|
|
573809
573892
|
"",
|
|
573810
573893
|
"A repeating identical error means the CHANGE ITSELF is wrong — an unsupported attribute/option, a wrong API/signature, or a missing prerequisite — NOT a value the agent hasn't guessed yet.",
|
|
573811
573894
|
"",
|
|
573895
|
+
stateDigest.trim(),
|
|
573896
|
+
"",
|
|
573812
573897
|
"Agent's latest message:",
|
|
573813
573898
|
obs.assistantText.slice(0, 900) || "(empty)",
|
|
573814
573899
|
"",
|
|
@@ -573819,12 +573904,32 @@ ${ls2.alreadyHave.slice(0, 900)}` : `(No cached result available for the repeate
|
|
|
573819
573904
|
"Return ONLY the JSON object."
|
|
573820
573905
|
].join("\n");
|
|
573821
573906
|
}
|
|
573907
|
+
if (obs.diagnosticSignal) {
|
|
573908
|
+
return [
|
|
573909
|
+
`The runtime queued a diagnostic trigger: ${obs.diagnosticSignal}.`,
|
|
573910
|
+
"This trigger is only a routing signal. Do NOT trust it as a verdict; classify from the world/progress digest and tool evidence.",
|
|
573911
|
+
stateDigest.trim(),
|
|
573912
|
+
"",
|
|
573913
|
+
"Agent's latest message:",
|
|
573914
|
+
obs.assistantText.slice(0, 1600) || "(empty)",
|
|
573915
|
+
"",
|
|
573916
|
+
"Recent tool outcomes:",
|
|
573917
|
+
outcomes || " (none)",
|
|
573918
|
+
priorDoubts ? `
|
|
573919
|
+
Unresolved doubts you raised earlier:
|
|
573920
|
+
${priorDoubts}` : "",
|
|
573921
|
+
"",
|
|
573922
|
+
"Decide whether there is a real contradiction, stale-state action, unproven claim, or no issue. Return ONLY the JSON object."
|
|
573923
|
+
].filter((line) => line !== "").join("\n");
|
|
573924
|
+
}
|
|
573822
573925
|
return [
|
|
573823
573926
|
obs.claimsCompletion ? "The agent is asserting COMPLETION this turn." : "The agent produced a progress/success-flavored claim this turn.",
|
|
573824
573927
|
"",
|
|
573825
573928
|
"Agent's latest message:",
|
|
573826
573929
|
obs.assistantText.slice(0, 1800) || "(empty)",
|
|
573827
573930
|
"",
|
|
573931
|
+
stateDigest.trim(),
|
|
573932
|
+
"",
|
|
573828
573933
|
"Recent tool outcomes (evidence available):",
|
|
573829
573934
|
outcomes || " (none)",
|
|
573830
573935
|
priorDoubts ? `
|
|
@@ -573959,14 +574064,16 @@ var init_adversaryStream = __esm({
|
|
|
573959
574064
|
return true;
|
|
573960
574065
|
if (obs.failingApproach)
|
|
573961
574066
|
return true;
|
|
574067
|
+
if (obs.diagnosticSignal)
|
|
574068
|
+
return true;
|
|
573962
574069
|
return SUCCESS_LANGUAGE.test(obs.assistantText);
|
|
573963
574070
|
}
|
|
573964
574071
|
/** Ingest an observation. Replaces any prior un-audited pending observation. */
|
|
573965
574072
|
observe(obs) {
|
|
573966
574073
|
if (!this.shouldAudit(obs))
|
|
573967
574074
|
return;
|
|
573968
|
-
const loopKey = obs.loopSignal ? `loop:${obs.loopSignal.tool}:${obs.loopSignal.target}:${obs.loopSignal.count}` : obs.failingApproach ? `fail:${obs.failingApproach.count}:${obs.failingApproach.sample.slice(0, 60)}` : "";
|
|
573969
|
-
const sig = `${obs.turn}:${loopKey}:${obs.assistantText.slice(0, 200)}`;
|
|
574075
|
+
const loopKey = obs.loopSignal ? `loop:${obs.loopSignal.tool}:${obs.loopSignal.target}:${obs.loopSignal.count}` : obs.failingApproach ? `fail:${obs.failingApproach.count}:${obs.failingApproach.sample.slice(0, 60)}` : obs.diagnosticSignal ? `diag:${obs.diagnosticSignal}` : "";
|
|
574076
|
+
const sig = `${obs.turn}:${loopKey}:${obs.assistantText.slice(0, 200)}:${obs.stateDigest?.slice(0, 120) ?? ""}`;
|
|
573970
574077
|
if (sig === this.lastAuditedSignature)
|
|
573971
574078
|
return;
|
|
573972
574079
|
this.pending = obs;
|
|
@@ -574783,8 +574890,13 @@ function violatesDirective(directive, input) {
|
|
|
574783
574890
|
if (directive.requiredNextAction !== "update_todos") {
|
|
574784
574891
|
if (directive.forbiddenActionFamilies.includes(family))
|
|
574785
574892
|
return true;
|
|
574786
|
-
if (directive.forbiddenActionFamilies.includes(input.toolName))
|
|
574893
|
+
if (directive.forbiddenActionFamilies.includes(input.toolName)) {
|
|
574894
|
+
if (input.toolName === "shell" && input.isReadLike)
|
|
574895
|
+
return false;
|
|
574896
|
+
if (input.toolName === "shell" && input.shellLikelyMutatesFilesystem)
|
|
574897
|
+
return false;
|
|
574787
574898
|
return true;
|
|
574899
|
+
}
|
|
574788
574900
|
}
|
|
574789
574901
|
switch (directive.requiredNextAction) {
|
|
574790
574902
|
case "update_todos":
|
|
@@ -574797,6 +574909,12 @@ function violatesDirective(directive, input) {
|
|
|
574797
574909
|
return !(input.toolName === "todo_write" || isEditTool(input.toolName));
|
|
574798
574910
|
case "read_authoritative_target":
|
|
574799
574911
|
return !(isEvidenceGatheringTool(input.toolName) || input.isReadLike);
|
|
574912
|
+
case "disambiguate_edit_match":
|
|
574913
|
+
if (isEditTool(input.toolName))
|
|
574914
|
+
return false;
|
|
574915
|
+
if (isEvidenceGatheringTool(input.toolName) || input.isReadLike)
|
|
574916
|
+
return false;
|
|
574917
|
+
return true;
|
|
574800
574918
|
case "run_verification":
|
|
574801
574919
|
return input.toolName !== "shell";
|
|
574802
574920
|
case "report_blocked":
|
|
@@ -574812,6 +574930,9 @@ function violatesDirective(directive, input) {
|
|
|
574812
574930
|
return false;
|
|
574813
574931
|
}
|
|
574814
574932
|
}
|
|
574933
|
+
function forbiddenCachedEvidenceFamilies(input, family) {
|
|
574934
|
+
return [family];
|
|
574935
|
+
}
|
|
574815
574936
|
function normalizeCompletionStatus(value2) {
|
|
574816
574937
|
if (typeof value2 !== "string")
|
|
574817
574938
|
return null;
|
|
@@ -574874,7 +574995,7 @@ function cleanFailureSample(text2) {
|
|
|
574874
574995
|
}
|
|
574875
574996
|
function failureErrorClass(text2) {
|
|
574876
574997
|
const normalized = String(text2 || "").toLowerCase();
|
|
574877
|
-
if (/ambiguous|multiple occurrences|matches more than once/.test(normalized)) {
|
|
574998
|
+
if (/ambiguous|not unique|multiple occurrences|matches more than once|found \d+ occurrences|has \d+ matches/.test(normalized)) {
|
|
574878
574999
|
return "stale_ambiguous_target";
|
|
574879
575000
|
}
|
|
574880
575001
|
if (/expected[_ -]?hash|hash mismatch|stale hash|beforehash|afterhash/.test(normalized)) {
|
|
@@ -574928,13 +575049,15 @@ function editTargetDescriptor(toolName, args) {
|
|
|
574928
575049
|
"expected_old_string",
|
|
574929
575050
|
"expectedHash",
|
|
574930
575051
|
"expected_hash",
|
|
575052
|
+
"replace_all",
|
|
575053
|
+
"replaceAll",
|
|
574931
575054
|
"mode",
|
|
574932
575055
|
"offset",
|
|
574933
575056
|
"limit",
|
|
574934
575057
|
"start_line"
|
|
574935
575058
|
]) {
|
|
574936
575059
|
const value2 = args[key];
|
|
574937
|
-
if (typeof value2 === "string" || typeof value2 === "number") {
|
|
575060
|
+
if (typeof value2 === "string" || typeof value2 === "number" || typeof value2 === "boolean") {
|
|
574938
575061
|
parts.push(`${key}=${String(value2)}`);
|
|
574939
575062
|
}
|
|
574940
575063
|
}
|
|
@@ -574946,7 +575069,8 @@ function editTargetDescriptor(toolName, args) {
|
|
|
574946
575069
|
const rec = edit;
|
|
574947
575070
|
const editPath = rec["path"] ?? rec["file"] ?? rec["filePath"] ?? rec["file_path"];
|
|
574948
575071
|
const target = rec["old_string"] ?? rec["oldString"] ?? rec["oldText"] ?? rec["search"] ?? rec["expected_old_string"] ?? rec["offset"] ?? rec["start_line"] ?? "";
|
|
574949
|
-
|
|
575072
|
+
const replaceAll = rec["replace_all"] === true || rec["replaceAll"] === true;
|
|
575073
|
+
parts.push(`${String(editPath ?? "")}=${String(target ?? "")}${replaceAll ? ":replace_all=true" : ""}`);
|
|
574950
575074
|
}
|
|
574951
575075
|
}
|
|
574952
575076
|
if (parts.length === 0 && toolName === "file_patch") {
|
|
@@ -575141,7 +575265,7 @@ var init_focusSupervisor = __esm({
|
|
|
575141
575265
|
state,
|
|
575142
575266
|
reason: input.cachedResultFailed ? `cached failed ${input.toolName} evidence already exists` : `duplicate ${input.toolName} call has cached evidence`,
|
|
575143
575267
|
requiredNextAction: "use_cached_evidence",
|
|
575144
|
-
forbiddenActionFamilies:
|
|
575268
|
+
forbiddenActionFamilies: forbiddenCachedEvidenceFamilies(input, family)
|
|
575145
575269
|
});
|
|
575146
575270
|
if (strict && !advisoryOnly && (input.cachedResultFailed || duplicateHitCount >= hitLimit)) {
|
|
575147
575271
|
return this.block(directive, [
|
|
@@ -575201,7 +575325,7 @@ var init_focusSupervisor = __esm({
|
|
|
575201
575325
|
return;
|
|
575202
575326
|
}
|
|
575203
575327
|
if (input.toolName === "file_read" && input.success) {
|
|
575204
|
-
if (this.directive?.requiredNextAction === "read_authoritative_target"
|
|
575328
|
+
if (this.directive?.requiredNextAction === "read_authoritative_target") {
|
|
575205
575329
|
this.clearSatisfiedDirective("authoritative evidence refreshed", input.turn);
|
|
575206
575330
|
}
|
|
575207
575331
|
return;
|
|
@@ -575209,8 +575333,10 @@ var init_focusSupervisor = __esm({
|
|
|
575209
575333
|
if (input.toolName === "shell" && input.success) {
|
|
575210
575334
|
if (this.directive?.requiredNextAction === "run_verification") {
|
|
575211
575335
|
this.clearSatisfiedDirective("verification ran successfully", input.turn);
|
|
575212
|
-
} else if (input.isReadLike &&
|
|
575336
|
+
} else if (input.isReadLike && this.directive?.requiredNextAction === "read_authoritative_target") {
|
|
575213
575337
|
this.clearSatisfiedDirective("authoritative evidence read via shell", input.turn);
|
|
575338
|
+
} else if (!input.isReadLike && this.directive?.requiredNextAction === "use_cached_evidence") {
|
|
575339
|
+
this.clearSatisfiedDirective("distinct shell action executed after cached evidence", input.turn);
|
|
575214
575340
|
}
|
|
575215
575341
|
return;
|
|
575216
575342
|
}
|
|
@@ -575226,26 +575352,29 @@ var init_focusSupervisor = __esm({
|
|
|
575226
575352
|
};
|
|
575227
575353
|
this.failureFamilies.set(family, next);
|
|
575228
575354
|
if (next.count >= 2) {
|
|
575355
|
+
const ambiguousEditFailure = isEditTool(input.toolName) && next.errorClass === "stale_ambiguous_target";
|
|
575229
575356
|
const staleEditFailure = isEditTool(input.toolName) && next.errorClass.startsWith("stale_");
|
|
575230
|
-
const forbidden = staleEditFailure ? uniqueLimited([
|
|
575357
|
+
const forbidden = staleEditFailure ? ambiguousEditFailure ? [actionFamily(input.toolName, input.args)] : uniqueLimited([
|
|
575231
575358
|
actionFamily(input.toolName, input.args),
|
|
575232
575359
|
input.toolName
|
|
575233
|
-
]) : [actionFamily(input.toolName, input.args)];
|
|
575360
|
+
]) : input.toolName === "shell" ? [actionFamily(input.toolName, input.args)] : [actionFamily(input.toolName, input.args)];
|
|
575234
575361
|
this.setDirective({
|
|
575235
575362
|
turn: input.turn,
|
|
575236
575363
|
state: "forced_replan",
|
|
575237
575364
|
reason: `same ${input.toolName} failure family repeated ${next.count} times: ${next.sample}`,
|
|
575238
|
-
requiredNextAction: staleEditFailure ? "read_authoritative_target" : input.toolName === "shell" ? "
|
|
575365
|
+
requiredNextAction: ambiguousEditFailure ? "disambiguate_edit_match" : staleEditFailure ? "read_authoritative_target" : input.toolName === "shell" ? "use_cached_evidence" : "update_todos",
|
|
575239
575366
|
forbiddenActionFamilies: forbidden
|
|
575240
575367
|
});
|
|
575241
575368
|
} else if (next.count === 1 && !this.directive) {
|
|
575369
|
+
const ambiguousEditFailure = isEditTool(input.toolName) && next.errorClass === "stale_ambiguous_target";
|
|
575242
575370
|
const staleEditFailure = isEditTool(input.toolName) && next.errorClass.startsWith("stale_");
|
|
575371
|
+
const shellFailure = input.toolName === "shell";
|
|
575243
575372
|
this.setDirective({
|
|
575244
575373
|
turn: input.turn,
|
|
575245
|
-
state: "warn",
|
|
575374
|
+
state: shellFailure ? "cached_evidence" : "warn",
|
|
575246
575375
|
reason: `first ${input.toolName} failure (${next.errorClass}): ${next.sample}`,
|
|
575247
|
-
requiredNextAction: staleEditFailure ? "read_authoritative_target" : "update_todos",
|
|
575248
|
-
forbiddenActionFamilies: [actionFamily(input.toolName, input.args)]
|
|
575376
|
+
requiredNextAction: ambiguousEditFailure ? "disambiguate_edit_match" : staleEditFailure ? "read_authoritative_target" : shellFailure ? "use_cached_evidence" : "update_todos",
|
|
575377
|
+
forbiddenActionFamilies: shellFailure ? [actionFamily(input.toolName, input.args)] : [actionFamily(input.toolName, input.args)]
|
|
575249
575378
|
});
|
|
575250
575379
|
}
|
|
575251
575380
|
}
|
|
@@ -577767,6 +577896,15 @@ function formatTodoReminderItems(todos, maxRows) {
|
|
|
577767
577896
|
rows.push(`... +${todos.length - rows.length} more`);
|
|
577768
577897
|
return rows.join("\n");
|
|
577769
577898
|
}
|
|
577899
|
+
function selectHeadTailLines(lines, headCount, tailCount) {
|
|
577900
|
+
if (lines.length <= headCount + tailCount)
|
|
577901
|
+
return lines;
|
|
577902
|
+
return [
|
|
577903
|
+
...lines.slice(0, headCount),
|
|
577904
|
+
`... [${lines.length - headCount - tailCount} middle line(s) omitted]`,
|
|
577905
|
+
...lines.slice(-tailCount)
|
|
577906
|
+
];
|
|
577907
|
+
}
|
|
577770
577908
|
function stripThinkBlocks(s2) {
|
|
577771
577909
|
if (!s2)
|
|
577772
577910
|
return s2;
|
|
@@ -578918,8 +579056,11 @@ ${parts.join("\n")}
|
|
|
578918
579056
|
case "update_todos":
|
|
578919
579057
|
return "todo_write with a changed plan/status, or a real file edit if that is the active work";
|
|
578920
579058
|
case "read_authoritative_target":
|
|
578921
|
-
case "use_cached_evidence":
|
|
578922
579059
|
return "use cached evidence or one authoritative file_read/read-only shell, then act";
|
|
579060
|
+
case "use_cached_evidence":
|
|
579061
|
+
return "do not rerun the blocked family; use the cached result to make a concrete edit, run a genuinely different diagnostic/verification command, or report incomplete";
|
|
579062
|
+
case "disambiguate_edit_match":
|
|
579063
|
+
return "file_edit or batch_edit with replace_all=true for identical global changes, or with a more unique old_string copied from current file context";
|
|
578923
579064
|
case "edit_different_target":
|
|
578924
579065
|
return "file_write, file_edit, batch_edit, or file_patch on a different supported target";
|
|
578925
579066
|
case "run_verification":
|
|
@@ -582836,13 +582977,11 @@ ${contentPreview}
|
|
|
582836
582977
|
for (const f2 of shown) {
|
|
582837
582978
|
const argsRepr = JSON.stringify(f2.args).slice(0, 120);
|
|
582838
582979
|
const failureText = [f2.error, f2.output].filter((v) => typeof v === "string" && v.trim().length > 0).join("\n");
|
|
582839
|
-
const
|
|
582840
|
-
const errFull = failureText.slice(0, f2.tool === "file_edit" || f2.tool === "batch_edit" || f2.tool === "file_patch" ? 1200 : 600);
|
|
582980
|
+
const excerpt = this._formatRecentFailureExcerpt(f2.tool, failureText);
|
|
582841
582981
|
lines.push(`• turn ${f2.turn} — ${f2.tool}(${argsRepr})`);
|
|
582842
|
-
lines.push(` first line: ${
|
|
582843
|
-
if (
|
|
582844
|
-
|
|
582845
|
-
lines.push(indented);
|
|
582982
|
+
lines.push(` first line: ${excerpt.firstLine}`);
|
|
582983
|
+
if (excerpt.body) {
|
|
582984
|
+
lines.push(excerpt.body);
|
|
582846
582985
|
}
|
|
582847
582986
|
}
|
|
582848
582987
|
if (repeating.length > 0) {
|
|
@@ -582852,6 +582991,14 @@ ${contentPreview}
|
|
|
582852
582991
|
lines.push(`(turn ${turn} — failures auto-expire after 10 turns; cleared on success or successful retry)`);
|
|
582853
582992
|
return lines.join("\n");
|
|
582854
582993
|
}
|
|
582994
|
+
_formatRecentFailureExcerpt(tool, text2) {
|
|
582995
|
+
const lines = String(text2 || "").replace(/\r/g, "").split("\n").map((line) => line.trimEnd());
|
|
582996
|
+
const firstLine = lines.find((line) => line.trim().length > 0)?.slice(0, 220) || "(no error message)";
|
|
582997
|
+
const maxChars = tool === "file_edit" || tool === "batch_edit" || tool === "file_patch" ? 1400 : tool === "shell" ? 2200 : 900;
|
|
582998
|
+
const selected = tool === "shell" ? selectHeadTailLines(lines, 8, 14) : lines.slice(0, 8);
|
|
582999
|
+
const body = selected.filter((line) => line.trim().length > 0).map((line) => ` ${line}`).join("\n").slice(0, maxChars);
|
|
583000
|
+
return { firstLine, body };
|
|
583001
|
+
}
|
|
582855
583002
|
/**
|
|
582856
583003
|
* Render a short, local-code-first nudge from the freshest failure signal.
|
|
582857
583004
|
* This is intentionally not a web-search suggestion: most coding-agent loops
|
|
@@ -585487,16 +585634,14 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
585487
585634
|
cwd: this._workingDirectory || process.cwd(),
|
|
585488
585635
|
model: this._backendModelLabel(this.backend),
|
|
585489
585636
|
onCritique: (critique2, sourceTurn) => {
|
|
585490
|
-
|
|
585491
|
-
|
|
585492
|
-
}
|
|
585493
|
-
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
585637
|
+
const runClosed = completed || this._completionIncompleteVerification || this.aborted;
|
|
585638
|
+
if (!runClosed && (this._adversaryMode === "skillcoach" || this._adversaryMode === "both")) {
|
|
585494
585639
|
this.pendingUserMessages.push(AdversaryStream.formatInjection(critique2));
|
|
585495
585640
|
}
|
|
585496
585641
|
this.emit({
|
|
585497
585642
|
type: "adversary_reaction",
|
|
585498
585643
|
adversary: {
|
|
585499
|
-
class: critique2.class === "
|
|
585644
|
+
class: critique2.class === "ok" ? "guidance" : critique2.class,
|
|
585500
585645
|
shortText: critique2.shortText,
|
|
585501
585646
|
confidence: critique2.confidence,
|
|
585502
585647
|
details: AdversaryStream.formatInjection(critique2)
|
|
@@ -585517,6 +585662,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
585517
585662
|
this._argCohorts.clear();
|
|
585518
585663
|
this._adversaryRedundantSignals.clear();
|
|
585519
585664
|
this._adversaryRecentFlags.clear();
|
|
585665
|
+
this._adversaryStateVersion = 0;
|
|
585520
585666
|
this._lastTodoWriteTurn = -1;
|
|
585521
585667
|
this._lastTodoReminderTurn = -1;
|
|
585522
585668
|
let pendingConstraintWarnings = [];
|
|
@@ -588378,6 +588524,7 @@ Read the current file if needed, make a different concrete edit, or move to veri
|
|
|
588378
588524
|
].includes(tc.name);
|
|
588379
588525
|
const isStatefulBrowserTool = this._isStatefulBrowserTool(tc.name);
|
|
588380
588526
|
const isReadLike = !isStatefulBrowserTool && (baseIsReadLike || tc.name === "shell" && this._isShellCommandReadOnly(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? ""));
|
|
588527
|
+
const shellLikelyMutatesFilesystem = tc.name === "shell" && this._shellCommandLikelyMutatesFilesystem(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? ""));
|
|
588381
588528
|
const adversaryRedundantSignal = this._adversaryRedundantSignals.has(toolFingerprint);
|
|
588382
588529
|
if (adversaryRedundantSignal) {
|
|
588383
588530
|
this._adversaryRedundantSignals.delete(toolFingerprint);
|
|
@@ -588453,13 +588600,10 @@ Read the current file if needed, make a different concrete edit, or move to veri
|
|
|
588453
588600
|
}
|
|
588454
588601
|
criticGuidance = criticDecision.guidanceMessage;
|
|
588455
588602
|
this.emit({
|
|
588456
|
-
type: "
|
|
588457
|
-
|
|
588458
|
-
|
|
588459
|
-
|
|
588460
|
-
confidence: 0.9,
|
|
588461
|
-
details: criticDecision.reason
|
|
588462
|
-
},
|
|
588603
|
+
type: "status",
|
|
588604
|
+
content: `Runtime cache guidance for repeated ${tc.name} call: ${criticDecision.reason}`,
|
|
588605
|
+
toolName: tc.name,
|
|
588606
|
+
turn,
|
|
588463
588607
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
588464
588608
|
});
|
|
588465
588609
|
if (this._adversaryStream && criticDecision.hitNumber >= 2) {
|
|
@@ -588489,6 +588633,9 @@ Read the current file if needed, make a different concrete edit, or move to veri
|
|
|
588489
588633
|
const _repeatGateMax = this._resolveRepeatGateMax();
|
|
588490
588634
|
const isFailedShellRepeat = tc.name === "shell" && typeof _existingFp?.result === "string" && _existingFp.result.includes("status: failure");
|
|
588491
588635
|
const repeatGateEligible = isReadLike || tc.name === "memory_write" || isFailedShellRepeat;
|
|
588636
|
+
const suppressSuccessfulShellCacheGuidance = tc.name === "shell" && !isFailedShellRepeat;
|
|
588637
|
+
if (suppressSuccessfulShellCacheGuidance)
|
|
588638
|
+
criticGuidance = null;
|
|
588492
588639
|
if (isReadLike && this._evidenceLedger) {
|
|
588493
588640
|
const readArgs = tc.arguments;
|
|
588494
588641
|
const readPath2 = String(readArgs?.["path"] ?? readArgs?.["file"] ?? "");
|
|
@@ -588534,10 +588681,10 @@ Read the current file if needed, make a different concrete edit, or move to veri
|
|
|
588534
588681
|
const cachedResult = this.sanitizeCachedToolResult(tc.name, _existingFp.result);
|
|
588535
588682
|
repeatShortCircuit = isFailedShellRepeat ? {
|
|
588536
588683
|
success: false,
|
|
588537
|
-
output: `[
|
|
588684
|
+
output: `[CACHED VERIFIER FAILURE — this same shell command already produced debugging evidence and was not re-executed unchanged. Treat the cached transcript below as the current failure signal. Change the code/config, run a genuinely different verifier/diagnostic command, or report the blocker with this evidence.]
|
|
588538
588685
|
|
|
588539
588686
|
${cachedResult}`,
|
|
588540
|
-
error: "
|
|
588687
|
+
error: "Cached verifier failure reused; command was not re-executed unchanged.",
|
|
588541
588688
|
runtimeAuthored: true
|
|
588542
588689
|
} : {
|
|
588543
588690
|
success: true,
|
|
@@ -588550,7 +588697,7 @@ ${cachedResult}`,
|
|
|
588550
588697
|
this.emit({
|
|
588551
588698
|
type: "status",
|
|
588552
588699
|
toolName: tc.name,
|
|
588553
|
-
content: repeatShortCircuit ? repeatShortCircuit.success ? `Exact repeat of ${tc.name} served from cache (hit #${criticDecision.hitNumber}); not re-executed` : `Exact repeat of ${tc.name} blocked after ${criticDecision.hitNumber} repeats; re-plan required` : `
|
|
588700
|
+
content: repeatShortCircuit ? repeatShortCircuit.success ? `Exact repeat of ${tc.name} served from cache (hit #${criticDecision.hitNumber}); not re-executed` : `Exact repeat of ${tc.name} blocked after ${criticDecision.hitNumber} repeats; re-plan required` : suppressSuccessfulShellCacheGuidance ? `Repeated successful shell command observed; re-executing because no state-independent verdict was made` : `Runtime cache guidance emitted for ${tc.name}; tool call will still execute`,
|
|
588554
588701
|
turn,
|
|
588555
588702
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
588556
588703
|
});
|
|
@@ -588564,6 +588711,7 @@ ${cachedResult}`,
|
|
|
588564
588711
|
completionStatus: completionStatusFromTaskCompleteArgs(tc.arguments),
|
|
588565
588712
|
fingerprint: toolFingerprint,
|
|
588566
588713
|
isReadLike,
|
|
588714
|
+
shellLikelyMutatesFilesystem,
|
|
588567
588715
|
cachedResult: focusCachedEntry?.result,
|
|
588568
588716
|
cachedResultFailed: tc.name === "shell" && typeof focusCachedEntry?.result === "string" && focusCachedEntry.result.includes("status: failure"),
|
|
588569
588717
|
duplicateHitCount: focusDuplicateHits,
|
|
@@ -588831,7 +588979,11 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
588831
588979
|
}
|
|
588832
588980
|
const shellFilesystemMutation = tc.name === "shell" && result.success === true && this._shellCommandLikelyMutatesFilesystem(String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? ""));
|
|
588833
588981
|
const realFileMutation = this._isRealProjectMutation(tc.name, result);
|
|
588982
|
+
const observedStateMutation = realFileMutation || shellFilesystemMutation || result.success === true && result.mutated === true;
|
|
588834
588983
|
const realMutationPaths = realFileMutation ? this._extractToolTargetPaths(tc.name, tc.arguments, result) : [];
|
|
588984
|
+
if (observedStateMutation) {
|
|
588985
|
+
this._markAdversaryObservedStateMutation();
|
|
588986
|
+
}
|
|
588835
588987
|
if (realFileMutation && this._reg61PerpetualGateActive) {
|
|
588836
588988
|
this._reg61PerpetualGateActive = false;
|
|
588837
588989
|
this.emit({
|
|
@@ -589671,8 +589823,10 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
589671
589823
|
}
|
|
589672
589824
|
if (isFileMutation && recentToolResults.size > 0) {
|
|
589673
589825
|
for (const key of Array.from(recentToolResults.keys())) {
|
|
589674
|
-
if (key.startsWith("shell:"))
|
|
589826
|
+
if (key.startsWith("shell:")) {
|
|
589675
589827
|
recentToolResults.delete(key);
|
|
589828
|
+
dedupHitCount.delete(key);
|
|
589829
|
+
}
|
|
589676
589830
|
}
|
|
589677
589831
|
}
|
|
589678
589832
|
if (isFileMutation) {
|
|
@@ -589712,7 +589866,7 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
589712
589866
|
fingerprint: toolFingerprint,
|
|
589713
589867
|
args: tc.arguments,
|
|
589714
589868
|
error: (result.error ?? "").slice(0, 600),
|
|
589715
|
-
output: (result.output ?? "").slice(0, 1500),
|
|
589869
|
+
output: (result.output ?? "").slice(0, tc.name === "shell" ? 4e3 : 1500),
|
|
589716
589870
|
turn
|
|
589717
589871
|
});
|
|
589718
589872
|
if (this._recentFailures.length > 8) {
|
|
@@ -593081,7 +593235,18 @@ ${folded}`);
|
|
|
593081
593235
|
buildRecoveryGuidance(toolName, error, args) {
|
|
593082
593236
|
const errLower = error.toLowerCase();
|
|
593083
593237
|
if (toolName === "file_edit" || toolName === "batch_edit") {
|
|
593084
|
-
if (
|
|
593238
|
+
if (/ambiguous|not unique|multiple occurrences|matches more than once|found \d+ occurrences|has \d+ matches/.test(errLower)) {
|
|
593239
|
+
if (toolName === "batch_edit") {
|
|
593240
|
+
return `[RECOVERY] batch_edit failed because at least one old_string matched multiple locations.
|
|
593241
|
+
ACTION: retry the affected edit with replace_all=true if every match should change identically, or add unique surrounding current file text to that edit's old_string if only one location should change. Do not switch to shell sed/perl/python rewrites.`;
|
|
593242
|
+
}
|
|
593243
|
+
const filePath = String(args["path"] ?? "the file");
|
|
593244
|
+
const oldStr = String(args["old_string"] ?? "").slice(0, 120);
|
|
593245
|
+
return `[RECOVERY] file_edit failed because old_string is ambiguous in ${filePath}.
|
|
593246
|
+
Attempted old_string preview: "${oldStr}".
|
|
593247
|
+
ACTION: retry file_edit with replace_all=true if every match should change identically, or use an old_string containing unique surrounding current file text for exactly one location. Do not retry the same old_string without replace_all, and do not switch to shell sed/perl/python rewrites.`;
|
|
593248
|
+
}
|
|
593249
|
+
if (errLower.includes("not found") || errLower.includes("no match") || errLower.includes("no occurrences") || errLower.includes("0 occurrences") || errLower.includes("could not find")) {
|
|
593085
593250
|
if (toolName === "batch_edit") {
|
|
593086
593251
|
const edits = Array.isArray(args["edits"]) ? args["edits"] : [];
|
|
593087
593252
|
const filePaths = [
|
|
@@ -594354,6 +594519,10 @@ ${trimmedNew}`;
|
|
|
594354
594519
|
// we add a second analysis path that catches mismatches in real-time.
|
|
594355
594520
|
/** Track recent tool outcomes for the adversary */
|
|
594356
594521
|
_adversaryToolOutcomes = [];
|
|
594522
|
+
/** Monotonic counter for observed local state changes.
|
|
594523
|
+
* Redundant-action classification is only valid within the same state
|
|
594524
|
+
* version; a repeated verifier after an edit is fresh evidence. */
|
|
594525
|
+
_adversaryStateVersion = 0;
|
|
594357
594526
|
/** WO-FIX-C: Tool fingerprints the adversary has flagged as redundant.
|
|
594358
594527
|
* Checked in executeSingle to attach advisory guidance before dispatch. */
|
|
594359
594528
|
_adversaryRedundantSignals = /* @__PURE__ */ new Set();
|
|
@@ -594368,6 +594537,59 @@ ${trimmedNew}`;
|
|
|
594368
594537
|
* Generates typed self-reflections on task failure and injects them
|
|
594369
594538
|
* into the next attempt's context for active learning. */
|
|
594370
594539
|
_reflectionBuffer = null;
|
|
594540
|
+
_markAdversaryObservedStateMutation() {
|
|
594541
|
+
this._adversaryStateVersion++;
|
|
594542
|
+
this._adversaryRedundantSignals.clear();
|
|
594543
|
+
for (const key of Array.from(this._adversaryRecentFlags.keys())) {
|
|
594544
|
+
if (key.startsWith("redundant_action:")) {
|
|
594545
|
+
this._adversaryRecentFlags.delete(key);
|
|
594546
|
+
}
|
|
594547
|
+
}
|
|
594548
|
+
}
|
|
594549
|
+
_buildAdversaryStateDigest(turn) {
|
|
594550
|
+
const ts = this._taskState;
|
|
594551
|
+
let todos = [];
|
|
594552
|
+
try {
|
|
594553
|
+
todos = this.readSessionTodos() ?? [];
|
|
594554
|
+
} catch {
|
|
594555
|
+
todos = [];
|
|
594556
|
+
}
|
|
594557
|
+
const todoCounts = {
|
|
594558
|
+
completed: todos.filter((t2) => t2.status === "completed").length,
|
|
594559
|
+
inProgress: todos.filter((t2) => t2.status === "in_progress").length,
|
|
594560
|
+
pending: todos.filter((t2) => t2.status === "pending").length,
|
|
594561
|
+
blocked: todos.filter((t2) => t2.status === "blocked").length
|
|
594562
|
+
};
|
|
594563
|
+
const activeTodos = todos.filter((t2) => t2.status === "in_progress" || t2.status === "blocked").slice(0, 4).map((t2) => `[${t2.status}] ${String(t2.content ?? "").slice(0, 120)}`);
|
|
594564
|
+
const modifiedFiles = [...ts.modifiedFiles.entries()].slice(-10).map(([path12, action]) => `${action}:${path12}`);
|
|
594565
|
+
const worldFiles = [...this._worldFacts.files.entries()].sort((a2, b) => (b[1].lastSeenTurn ?? 0) - (a2[1].lastSeenTurn ?? 0)).slice(0, 8).map(([path12, fact]) => {
|
|
594566
|
+
const write2 = fact.lastWriteTurn ? ` write@${fact.lastWriteTurn}` : "";
|
|
594567
|
+
const seen = `seen@${fact.lastSeenTurn}`;
|
|
594568
|
+
const wc = fact.writeCount ? ` writes=${fact.writeCount}` : "";
|
|
594569
|
+
return `${path12} (${seen}${write2}${wc})`;
|
|
594570
|
+
});
|
|
594571
|
+
const recentFailures = this._recentFailures.slice(-5).map((failure) => {
|
|
594572
|
+
const text2 = (failure.error || failure.output || "").replace(/\s+/g, " ").trim().slice(0, 180);
|
|
594573
|
+
return `${failure.tool}: ${text2}`;
|
|
594574
|
+
});
|
|
594575
|
+
const focus = this._focusSupervisor?.snapshot().directive;
|
|
594576
|
+
const lines = [
|
|
594577
|
+
`[WORLD STATE SUMMARY] turn=${turn} state_version=${this._adversaryStateVersion}`,
|
|
594578
|
+
`goal=${(ts.originalGoal || ts.goal || "").slice(0, 260)}`,
|
|
594579
|
+
`phase=${ts.phase ?? "unknown"} current_step=${(ts.currentStep || "none").slice(0, 180)}`,
|
|
594580
|
+
ts.nextAction ? `next_action=${ts.nextAction.slice(0, 180)}` : "",
|
|
594581
|
+
`progress=todos completed:${todoCounts.completed} in_progress:${todoCounts.inProgress} pending:${todoCounts.pending} blocked:${todoCounts.blocked}; completed_steps:${ts.completedSteps.length}; failed_approaches:${ts.failedApproaches.length}; modified_files:${ts.modifiedFiles.size}; tool_calls:${ts.toolCallCount}`,
|
|
594582
|
+
activeTodos.length ? `active_todos=${activeTodos.join(" | ")}` : "",
|
|
594583
|
+
ts.completedSteps.length ? `recent_completed=${ts.completedSteps.slice(-5).join(" | ").slice(0, 500)}` : "",
|
|
594584
|
+
ts.failedApproaches.length ? `recent_failed_approaches=${ts.failedApproaches.slice(-4).join(" | ").slice(0, 500)}` : "",
|
|
594585
|
+
modifiedFiles.length ? `modified_files_recent=${modifiedFiles.join(" | ").slice(0, 700)}` : "",
|
|
594586
|
+
worldFiles.length ? `world_files_recent=${worldFiles.join(" | ").slice(0, 700)}` : "",
|
|
594587
|
+
this._worldFacts.lastTest.summary ? `last_verification=${this._worldFacts.lastTest.passed ? "passed" : "failed"} turn=${this._worldFacts.lastTest.turn ?? "?"}: ${this._worldFacts.lastTest.summary.slice(0, 260)}` : "",
|
|
594588
|
+
recentFailures.length ? `recent_failures=${recentFailures.join(" | ").slice(0, 700)}` : "",
|
|
594589
|
+
focus ? `focus=${focus.requiredNextAction}: ${focus.reason.slice(0, 240)}` : ""
|
|
594590
|
+
].filter(Boolean);
|
|
594591
|
+
return lines.join("\n").slice(0, 2600);
|
|
594592
|
+
}
|
|
594371
594593
|
buildAdversaryToolOutcomeEvidence(toolName, toolArgs, content, succeeded) {
|
|
594372
594594
|
const pathValue = toolArgs?.["path"] ?? toolArgs?.["file"] ?? toolArgs?.["filePath"] ?? toolArgs?.["file_path"];
|
|
594373
594595
|
const path12 = typeof pathValue === "string" && pathValue.trim() ? pathValue.trim() : void 0;
|
|
@@ -594451,6 +594673,7 @@ ${trimmedNew}`;
|
|
|
594451
594673
|
toolCallId: msg.tool_call_id,
|
|
594452
594674
|
argsKey,
|
|
594453
594675
|
fingerprint,
|
|
594676
|
+
stateVersion: this._adversaryStateVersion,
|
|
594454
594677
|
succeeded,
|
|
594455
594678
|
...outcomeEvidence
|
|
594456
594679
|
});
|
|
@@ -594459,136 +594682,66 @@ ${trimmedNew}`;
|
|
|
594459
594682
|
}
|
|
594460
594683
|
while (this._adversaryToolOutcomes.length > 20)
|
|
594461
594684
|
this._adversaryToolOutcomes.shift();
|
|
594462
|
-
|
|
594463
|
-
|
|
594464
|
-
|
|
594465
|
-
|
|
594466
|
-
|
|
594467
|
-
|
|
594468
|
-
|
|
594469
|
-
|
|
594470
|
-
|
|
594471
|
-
|
|
594472
|
-
|
|
594473
|
-
|
|
594474
|
-
|
|
594475
|
-
|
|
594476
|
-
|
|
594477
|
-
|
|
594478
|
-
|
|
594479
|
-
|
|
594480
|
-
|
|
594481
|
-
|
|
594482
|
-
|
|
594483
|
-
|
|
594484
|
-
if (turn - val.lastTurn > _AgenticRunner.ADVERSARY_FLAG_TTL)
|
|
594485
|
-
this._adversaryRecentFlags.delete(key);
|
|
594486
|
-
}
|
|
594487
|
-
const adversaryFlag = (flagKey, messages3) => {
|
|
594488
|
-
const existing = this._adversaryRecentFlags.get(flagKey);
|
|
594489
|
-
if (existing) {
|
|
594490
|
-
existing.count++;
|
|
594491
|
-
existing.lastTurn = turn;
|
|
594492
|
-
if (existing.count >= _AgenticRunner.ADVERSARY_ESCALATE_THRESHOLD) {
|
|
594493
|
-
return "escalate";
|
|
594494
|
-
}
|
|
594495
|
-
return "suppress";
|
|
594496
|
-
}
|
|
594497
|
-
this._adversaryRecentFlags.set(flagKey, { count: 1, lastTurn: turn });
|
|
594498
|
-
return "proceed";
|
|
594499
|
-
};
|
|
594500
|
-
const emitReaction = (cls, shortText, confidence2, details2) => {
|
|
594685
|
+
const stateDigest = this._buildAdversaryStateDigest(turn);
|
|
594686
|
+
const recentToolOutcomes = this._adversaryToolOutcomes.slice(-8).map((o2) => ({
|
|
594687
|
+
tool: o2.tool,
|
|
594688
|
+
succeeded: o2.succeeded,
|
|
594689
|
+
preview: o2.preview,
|
|
594690
|
+
path: o2.path,
|
|
594691
|
+
evidence: o2.evidence
|
|
594692
|
+
}));
|
|
594693
|
+
const queueAdversaryAudit = (input, reason) => {
|
|
594694
|
+
if (!this._adversaryStream || this._completionIncompleteVerification)
|
|
594695
|
+
return;
|
|
594696
|
+
const observation = {
|
|
594697
|
+
turn,
|
|
594698
|
+
recentToolOutcomes,
|
|
594699
|
+
stateDigest,
|
|
594700
|
+
...input
|
|
594701
|
+
};
|
|
594702
|
+
if (!this._adversaryStream.shouldAudit(observation))
|
|
594703
|
+
return;
|
|
594704
|
+
this._adversaryStream.observe(observation);
|
|
594705
|
+
void this._adversaryStream.tick().catch(() => {
|
|
594706
|
+
});
|
|
594501
594707
|
this.emit({
|
|
594502
|
-
type: "
|
|
594503
|
-
|
|
594504
|
-
|
|
594708
|
+
type: "status",
|
|
594709
|
+
content: `Adversary inference queued: ${reason}`,
|
|
594710
|
+
turn,
|
|
594711
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
594505
594712
|
});
|
|
594506
594713
|
};
|
|
594507
|
-
const buildAdversaryCritique = (input) => {
|
|
594508
|
-
const alternatives = input.alternatives && input.alternatives.length > 0 ? `
|
|
594509
|
-
Alternatives:
|
|
594510
|
-
${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
594511
|
-
return [
|
|
594512
|
-
`[ADVERSARY CRITIQUE — non-blocking]`,
|
|
594513
|
-
`Evidence: ${input.evidence}`,
|
|
594514
|
-
`Root cause hypothesis: ${input.hypothesis}`,
|
|
594515
|
-
`Corrective action: ${input.correctiveAction}${alternatives}`
|
|
594516
|
-
].join("\n");
|
|
594517
|
-
};
|
|
594518
594714
|
const lastAssistant = [...recent].reverse().find((m2) => m2.role === "assistant" && typeof m2.content === "string");
|
|
594519
594715
|
if (lastAssistant && typeof lastAssistant.content === "string") {
|
|
594520
|
-
const
|
|
594716
|
+
const assistantText = lastAssistant.content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
594717
|
+
const text2 = assistantText.toLowerCase();
|
|
594718
|
+
const claimsCompletion = /task.?complete|all tests pass|\bdone\b|\bcomplete(d)?\b/i.test(text2);
|
|
594719
|
+
queueAdversaryAudit({
|
|
594720
|
+
assistantText,
|
|
594721
|
+
claimsCompletion
|
|
594722
|
+
}, claimsCompletion ? "completion/progress claim" : "success-language audit");
|
|
594521
594723
|
const claimsFailure = /(?:fail|error|didn't work|not working|unable to|cannot|couldn't|both .* fail|tools? (?:have |has )?been fail)/i.test(text2);
|
|
594522
594724
|
if (claimsFailure) {
|
|
594523
594725
|
const recentOutcomes = this._adversaryToolOutcomes.slice(-4);
|
|
594524
594726
|
const successes = recentOutcomes.filter((o2) => o2.succeeded);
|
|
594525
594727
|
if (successes.length >= 1) {
|
|
594526
|
-
|
|
594527
|
-
|
|
594528
|
-
|
|
594529
|
-
|
|
594530
|
-
|
|
594531
|
-
hypothesis: "The main loop is interpreting uncertainty or partial progress as failure and may be about to discard usable evidence.",
|
|
594532
|
-
correctiveAction: "Use the successful results to advance the task, then verify the next concrete step.",
|
|
594533
|
-
alternatives: [
|
|
594534
|
-
"Edit or run the next verification step that follows from the successful output.",
|
|
594535
|
-
"Read a different targeted file if the successful result exposed a new path or symbol.",
|
|
594536
|
-
"Complete only if the successful output is sufficient evidence for the user's request."
|
|
594537
|
-
]
|
|
594538
|
-
});
|
|
594539
|
-
emitReaction("false_failure", `Claimed failure, but recent tools succeeded (${successes.length})`, 0.9, successList);
|
|
594540
|
-
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
594541
|
-
if (ffFlag === "escalate") {
|
|
594542
|
-
messages2.push({
|
|
594543
|
-
role: "system",
|
|
594544
|
-
content: critiqueText + "\n[ESCALATED: This warning was previously issued without effect.]"
|
|
594545
|
-
});
|
|
594546
|
-
} else {
|
|
594547
|
-
this.pendingUserMessages.push(critiqueText);
|
|
594548
|
-
}
|
|
594549
|
-
}
|
|
594550
|
-
this.emit({
|
|
594551
|
-
type: "status",
|
|
594552
|
-
content: `\x1B[38;5;178m⚠ Corrected false failure claim (${successes.length} tools succeeded)\x1B[0m`,
|
|
594553
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
594554
|
-
});
|
|
594555
|
-
}
|
|
594728
|
+
queueAdversaryAudit({
|
|
594729
|
+
assistantText,
|
|
594730
|
+
claimsCompletion: false,
|
|
594731
|
+
diagnosticSignal: "possible_false_failure"
|
|
594732
|
+
}, `possible false-failure claim after ${successes.length} successful tool outcome(s)`);
|
|
594556
594733
|
}
|
|
594557
594734
|
}
|
|
594558
|
-
}
|
|
594559
|
-
if (lastAssistant && typeof lastAssistant.content === "string") {
|
|
594560
|
-
const text2 = lastAssistant.content.toLowerCase();
|
|
594561
594735
|
const claimsSuccess = /(done|fixed|success|passed|complete)/i.test(text2);
|
|
594562
594736
|
if (claimsSuccess) {
|
|
594563
594737
|
const recentOutcomes = this._adversaryToolOutcomes.slice(-4);
|
|
594564
594738
|
const failures = recentOutcomes.filter((o2) => !o2.succeeded);
|
|
594565
|
-
|
|
594566
|
-
|
|
594567
|
-
|
|
594568
|
-
|
|
594569
|
-
|
|
594570
|
-
|
|
594571
|
-
evidence: `Recent tools show errors (${failures.length}): ${failList}.`,
|
|
594572
|
-
hypothesis: "The main loop is prematurely compressing intent into success language before the verifier produced evidence.",
|
|
594573
|
-
correctiveAction: "Inspect the failed output, identify the implicated path/symbol/command, and run one focused corrective step before claiming success.",
|
|
594574
|
-
alternatives: [
|
|
594575
|
-
"Read the smallest relevant source region around the failed symbol.",
|
|
594576
|
-
"Patch the implicated code or configuration.",
|
|
594577
|
-
"Run the same verifier only after a state-changing fix."
|
|
594578
|
-
]
|
|
594579
|
-
});
|
|
594580
|
-
emitReaction("false_success", `Claimed success, but recent tools failed (${failures.length})`, 0.9, failList);
|
|
594581
|
-
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
594582
|
-
if (fsFlag === "escalate") {
|
|
594583
|
-
messages2.push({
|
|
594584
|
-
role: "system",
|
|
594585
|
-
content: critiqueText + "\n[ESCALATED: This warning was previously issued without effect.]"
|
|
594586
|
-
});
|
|
594587
|
-
} else {
|
|
594588
|
-
this.pendingUserMessages.push(critiqueText);
|
|
594589
|
-
}
|
|
594590
|
-
}
|
|
594591
|
-
}
|
|
594739
|
+
if (failures.length > 0) {
|
|
594740
|
+
queueAdversaryAudit({
|
|
594741
|
+
assistantText,
|
|
594742
|
+
claimsCompletion,
|
|
594743
|
+
diagnosticSignal: "possible_false_success"
|
|
594744
|
+
}, `possible false-success claim near ${failures.length} recent failure(s)`);
|
|
594592
594745
|
}
|
|
594593
594746
|
}
|
|
594594
594747
|
}
|
|
@@ -594606,38 +594759,20 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
594606
594759
|
}
|
|
594607
594760
|
const argsKey = this._buildExactArgsKey(args);
|
|
594608
594761
|
const fingerprint = this._buildToolFingerprint(name10, args);
|
|
594609
|
-
const prior = this._adversaryToolOutcomes.find((o2) => o2.succeeded && o2.tool === name10 && o2.fingerprint === fingerprint && o2.turn < turn);
|
|
594762
|
+
const prior = this._adversaryToolOutcomes.find((o2) => o2.succeeded && o2.tool === name10 && o2.fingerprint === fingerprint && o2.stateVersion === this._adversaryStateVersion && o2.turn < turn);
|
|
594610
594763
|
if (prior) {
|
|
594611
|
-
this.
|
|
594612
|
-
|
|
594613
|
-
|
|
594614
|
-
|
|
594615
|
-
|
|
594616
|
-
|
|
594617
|
-
|
|
594618
|
-
|
|
594619
|
-
|
|
594620
|
-
|
|
594621
|
-
|
|
594622
|
-
|
|
594623
|
-
});
|
|
594624
|
-
emitReaction("redundant_action", `Already ran ${name10} successfully on turn ${prior.turn}`, 0.8, prior.preview);
|
|
594625
|
-
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
594626
|
-
if (raFlag === "escalate") {
|
|
594627
|
-
messages2.push({
|
|
594628
|
-
role: "system",
|
|
594629
|
-
content: critiqueText + "\n[ESCALATED: This redundant-action warning was issued 3+ times as a user message without effect.]"
|
|
594630
|
-
});
|
|
594631
|
-
} else {
|
|
594632
|
-
this.pendingUserMessages.push(critiqueText);
|
|
594633
|
-
}
|
|
594634
|
-
}
|
|
594635
|
-
this.emit({
|
|
594636
|
-
type: "status",
|
|
594637
|
-
content: `\x1B[38;5;178m⚠ Adversary noted redundant ${name10} call (succeeded on turn ${prior.turn}); action remains allowed\x1B[0m`,
|
|
594638
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
594639
|
-
});
|
|
594640
|
-
}
|
|
594764
|
+
const repeatCount = this._adversaryToolOutcomes.filter((o2) => o2.tool === name10 && o2.fingerprint === fingerprint && o2.stateVersion === this._adversaryStateVersion && o2.turn < turn).length + 1;
|
|
594765
|
+
queueAdversaryAudit({
|
|
594766
|
+
assistantText: "",
|
|
594767
|
+
claimsCompletion: false,
|
|
594768
|
+
diagnosticSignal: "possible_repeated_action",
|
|
594769
|
+
loopSignal: {
|
|
594770
|
+
tool: name10,
|
|
594771
|
+
target: argsKey.slice(0, 180),
|
|
594772
|
+
count: repeatCount,
|
|
594773
|
+
alreadyHave: prior.preview
|
|
594774
|
+
}
|
|
594775
|
+
}, `possible repeated action ${name10} after prior same-state success`);
|
|
594641
594776
|
break;
|
|
594642
594777
|
}
|
|
594643
594778
|
}
|
|
@@ -594655,35 +594790,11 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
594655
594790
|
}
|
|
594656
594791
|
}
|
|
594657
594792
|
if (consecutiveShortResults >= 3) {
|
|
594658
|
-
|
|
594659
|
-
|
|
594660
|
-
|
|
594661
|
-
|
|
594662
|
-
|
|
594663
|
-
correctiveAction: "Take one input/observation step before another output step.",
|
|
594664
|
-
alternatives: [
|
|
594665
|
-
"Call the input/listen/poll tool for the current environment.",
|
|
594666
|
-
"Read the current UI/page state before clicking or typing again.",
|
|
594667
|
-
"If the task is already complete, finish with the concrete evidence already observed."
|
|
594668
|
-
]
|
|
594669
|
-
});
|
|
594670
|
-
emitReaction("idle_think", `Consecutive output without input: ${consecutiveShortResults}`, 0.7);
|
|
594671
|
-
if (this._adversaryMode === "skillcoach" || this._adversaryMode === "both") {
|
|
594672
|
-
if (itFlag === "escalate") {
|
|
594673
|
-
messages2.push({
|
|
594674
|
-
role: "system",
|
|
594675
|
-
content: critiqueText + "\n[ESCALATED: This warning was previously issued without effect.]"
|
|
594676
|
-
});
|
|
594677
|
-
} else {
|
|
594678
|
-
this.pendingUserMessages.push(critiqueText);
|
|
594679
|
-
}
|
|
594680
|
-
}
|
|
594681
|
-
this.emit({
|
|
594682
|
-
type: "status",
|
|
594683
|
-
content: `\x1B[38;5;178m⚠ Adversary flagged runaway-output risk (${consecutiveShortResults} consecutive sends without receive); action remains allowed\x1B[0m`,
|
|
594684
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
594685
|
-
});
|
|
594686
|
-
}
|
|
594793
|
+
queueAdversaryAudit({
|
|
594794
|
+
assistantText: "",
|
|
594795
|
+
claimsCompletion: false,
|
|
594796
|
+
diagnosticSignal: "possible_stale_output"
|
|
594797
|
+
}, `possible stale-output loop (${consecutiveShortResults} short successful outcomes)`);
|
|
594687
594798
|
}
|
|
594688
594799
|
}
|
|
594689
594800
|
}
|
|
@@ -594691,6 +594802,8 @@ ${input.alternatives.map((item) => `- ${item}`).join("\n")}` : "";
|
|
|
594691
594802
|
const failCount = this._adversaryToolOutcomes.filter((o2) => !o2.succeeded).length;
|
|
594692
594803
|
const lastFour = this._adversaryToolOutcomes.slice(-4);
|
|
594693
594804
|
const details = [
|
|
594805
|
+
stateDigest,
|
|
594806
|
+
``,
|
|
594694
594807
|
`Recent tool outcomes:`,
|
|
594695
594808
|
...lastFour.map((o2) => `- ${o2.tool}: ${o2.succeeded ? "OK" : "ERR"} — ${o2.preview}`)
|
|
594696
594809
|
].join("\n");
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.456",
|
|
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.456",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED