omnius 1.0.468 → 1.0.470
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 +208 -235
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14298,27 +14298,62 @@ function replaceAllOccurrences(haystack, needle, replacement) {
|
|
|
14298
14298
|
return haystack.split(needle).join(replacement);
|
|
14299
14299
|
}
|
|
14300
14300
|
function buildMissingOldStringLlmContent(input) {
|
|
14301
|
+
const attemptedLineCount = input.attemptedOldString.split("\n").length;
|
|
14302
|
+
const attemptedCharCount = input.attemptedOldString.length;
|
|
14301
14303
|
const lines = [
|
|
14302
14304
|
"[FILE_EDIT_OLD_STRING_NOT_FOUND]",
|
|
14303
14305
|
`path=${input.path}`,
|
|
14304
14306
|
"The attempted old_string was absent from the current file.",
|
|
14307
|
+
`attempted_old_string_lines=${attemptedLineCount}`,
|
|
14308
|
+
`attempted_old_string_chars=${attemptedCharCount}`,
|
|
14309
|
+
"repair_state=needs_current_range",
|
|
14310
|
+
"patch_ready=false",
|
|
14311
|
+
"read_required=true unless current path+start_line+end_line+expected_hash are already present in active evidence",
|
|
14305
14312
|
"Do not copy diagnostic gutters into old_string. Ignore line numbers, leading '>' markers, and the '|' separator.",
|
|
14313
|
+
"Transport rule: file_edit is for exact unique current text. If the intended edit is a contiguous line-range delete/replace/insert, use file_patch with start_line/end_line from file_read and expected_hash or expected_old_content.",
|
|
14314
|
+
"Range patch contract: if patch_ready=true or current target line range plus expected_hash are known, call file_patch. If the range/hash is missing after stale exact edit failure, file_read the target once.",
|
|
14306
14315
|
"",
|
|
14307
|
-
"attempted_old_string
|
|
14308
|
-
fencedText(input.attemptedOldString)
|
|
14316
|
+
...diagnosticTextBlock("attempted_old_string", input.attemptedOldString)
|
|
14309
14317
|
];
|
|
14310
14318
|
if (input.snippetContent) {
|
|
14311
14319
|
const range = input.snippetStartLine && input.snippetEndLine && input.totalLines ? `lines ${input.snippetStartLine}-${input.snippetEndLine} of ${input.totalLines}` : "closest current text";
|
|
14312
|
-
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
|
|
14320
|
+
lines.push("", `current_anchor_range=${range}`, "target_range_status=anchor_only_not_patch_ready", `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 use file_patch from fresh file_read line numbers when the target is a block/range.");
|
|
14313
14321
|
} else {
|
|
14314
|
-
lines.push("", "Next action: file_read the target, then build old_string from exact current file content.");
|
|
14322
|
+
lines.push("", "Next action: file_read the target, then either build old_string from exact current file content or use file_patch for a line-range edit.");
|
|
14315
14323
|
}
|
|
14316
14324
|
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.");
|
|
14317
14325
|
if (input.newString.length > 0) {
|
|
14318
|
-
lines.push("", "desired_new_string
|
|
14326
|
+
lines.push("", ...diagnosticTextBlock("desired_new_string", input.newString));
|
|
14319
14327
|
}
|
|
14320
14328
|
return lines.join("\n");
|
|
14321
14329
|
}
|
|
14330
|
+
function diagnosticTextBlock(label, text2) {
|
|
14331
|
+
const maxChars = 700;
|
|
14332
|
+
const maxLines = 12;
|
|
14333
|
+
const lineCount = text2.split("\n").length;
|
|
14334
|
+
if (text2.length <= maxChars && lineCount <= maxLines) {
|
|
14335
|
+
return [`${label}:`, fencedText(text2)];
|
|
14336
|
+
}
|
|
14337
|
+
return [
|
|
14338
|
+
`${label}_preview:`,
|
|
14339
|
+
fencedText(previewText(text2, maxChars)),
|
|
14340
|
+
`${label}_omitted=true`,
|
|
14341
|
+
`${label}_omitted_reason=stale failed edit payload is not authoritative current file evidence`
|
|
14342
|
+
];
|
|
14343
|
+
}
|
|
14344
|
+
function previewText(text2, maxChars) {
|
|
14345
|
+
if (text2.length <= maxChars)
|
|
14346
|
+
return text2;
|
|
14347
|
+
const headSize = Math.floor(maxChars * 0.65);
|
|
14348
|
+
const tailSize = Math.max(80, maxChars - headSize - 64);
|
|
14349
|
+
const head = text2.slice(0, headSize).trimEnd();
|
|
14350
|
+
const tail = text2.slice(-tailSize).trimStart();
|
|
14351
|
+
return `${head}
|
|
14352
|
+
...
|
|
14353
|
+
[omitted ${text2.length - head.length - tail.length} chars]
|
|
14354
|
+
...
|
|
14355
|
+
${tail}`;
|
|
14356
|
+
}
|
|
14322
14357
|
function buildAmbiguousOldStringLlmContent(input) {
|
|
14323
14358
|
const replaceAllArgs = {
|
|
14324
14359
|
path: input.path,
|
|
@@ -14367,7 +14402,7 @@ var init_file_edit = __esm({
|
|
|
14367
14402
|
init_text_encoding();
|
|
14368
14403
|
FileEditTool = class {
|
|
14369
14404
|
name = "file_edit";
|
|
14370
|
-
description = "Make a precise edit to a file by replacing an exact string match. The old_string must be unique in the file unless replace_all is true. Use replace_all to rename variables or change repeated patterns throughout the file.";
|
|
14405
|
+
description = "Make a precise edit to a file by replacing an exact string match. The old_string must be unique in the file unless replace_all is true. Use replace_all to rename variables or change repeated patterns throughout the file. Use file_patch instead when file_read line numbers identify a contiguous block to delete, replace, or insert around.";
|
|
14371
14406
|
parameters = {
|
|
14372
14407
|
type: "object",
|
|
14373
14408
|
properties: {
|
|
@@ -14490,6 +14525,8 @@ var init_file_edit = __esm({
|
|
|
14490
14525
|
}
|
|
14491
14526
|
}
|
|
14492
14527
|
if (occurrences === 0) {
|
|
14528
|
+
const attemptedOldStringLines = oldString.split("\n").length;
|
|
14529
|
+
const attemptedOldStringChars = oldString.length;
|
|
14493
14530
|
const alreadyAppliedLines = newString.length > 0 ? findMatchLines(content, newString) : [];
|
|
14494
14531
|
if (alreadyAppliedLines.length > 0) {
|
|
14495
14532
|
const lineInfo = alreadyAppliedLines.length === 1 ? `line ${alreadyAppliedLines[0]}` : `${alreadyAppliedLines.length} locations (lines ${alreadyAppliedLines.join(", ")})`;
|
|
@@ -14512,10 +14549,12 @@ var init_file_edit = __esm({
|
|
|
14512
14549
|
const pct = Math.round(snippet.similarity * 100);
|
|
14513
14550
|
errorMsg += `
|
|
14514
14551
|
|
|
14515
|
-
|
|
14552
|
+
Attempted old_string spans ${attemptedOldStringLines} line(s), ${attemptedOldStringChars} chars. The diagnostic below is the closest anchor-line match, not proof that the whole old_string exists.
|
|
14553
|
+
|
|
14554
|
+
Current file content (closest anchor-line match, ${pct}% line similarity, lines ${snippet.startLine}–${snippet.endLine} of ${snippet.totalLines}):
|
|
14516
14555
|
${snippet.content}
|
|
14517
14556
|
|
|
14518
|
-
Use the EXACT current content above to construct a working old_string. Do not retry with a different guess — the file on disk has changed since you last read it.`;
|
|
14557
|
+
Use the EXACT current content above to construct a working old_string. If the intended change is a contiguous line range, use file_patch with start_line/end_line from a fresh file_read. Do not retry with a different guess — the file on disk has changed since you last read it.`;
|
|
14519
14558
|
} else {
|
|
14520
14559
|
errorMsg += ` The file is empty or binary. Use file_read to inspect.`;
|
|
14521
14560
|
}
|
|
@@ -28917,7 +28956,7 @@ var init_file_patch = __esm({
|
|
|
28917
28956
|
init_text_encoding();
|
|
28918
28957
|
FilePatchTool = class {
|
|
28919
28958
|
name = "file_patch";
|
|
28920
|
-
description = "Edit specific line ranges in a file. More precise than string matching for large files. Modes: 'replace' replaces lines start_line..end_line with new_content, 'insert_before' inserts before start_line, 'insert_after' inserts after start_line, 'delete' removes lines start_line..end_line. Use dry_run to preview changes.";
|
|
28959
|
+
description = "Edit specific line ranges in a file. More precise than string matching for large files. Modes: 'replace' replaces lines start_line..end_line with new_content, 'insert_before' inserts before start_line, 'insert_after' inserts after start_line, 'delete' removes lines start_line..end_line. Use this instead of file_edit when file_read line numbers identify the contiguous block to change. Use dry_run to preview changes.";
|
|
28921
28960
|
parameters = {
|
|
28922
28961
|
type: "object",
|
|
28923
28962
|
properties: {
|
|
@@ -575475,7 +575514,7 @@ function compactCachedEvidence(text2) {
|
|
|
575475
575514
|
const lineCount = value2 ? value2.split("\n").length : 0;
|
|
575476
575515
|
const sha = value2.match(/sha256=([a-f0-9]{8,64})/i)?.[1];
|
|
575477
575516
|
const header = value2.match(/\[FILE CONTEXT \|[^\]]+\]/)?.[0];
|
|
575478
|
-
const preview = value2
|
|
575517
|
+
const preview = meaningfulCachedEvidencePreview(value2);
|
|
575479
575518
|
return [
|
|
575480
575519
|
"Cached evidence is already available in the active context/tool cache; full payload omitted from this block to avoid context bloat.",
|
|
575481
575520
|
`cached_size=${lineCount} lines, ${value2.length} chars`,
|
|
@@ -575485,6 +575524,35 @@ function compactCachedEvidence(text2) {
|
|
|
575485
575524
|
"Use the cached evidence now, or request a distinct offset/limit/query if genuinely needed."
|
|
575486
575525
|
].filter(Boolean).join("\n");
|
|
575487
575526
|
}
|
|
575527
|
+
function meaningfulCachedEvidencePreview(text2) {
|
|
575528
|
+
const lines = text2.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
575529
|
+
const preview = [];
|
|
575530
|
+
const push = (value2) => {
|
|
575531
|
+
if (!value2)
|
|
575532
|
+
return;
|
|
575533
|
+
if (preview.includes(value2))
|
|
575534
|
+
return;
|
|
575535
|
+
preview.push(value2);
|
|
575536
|
+
};
|
|
575537
|
+
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
575538
|
+
const line = lines[i2];
|
|
575539
|
+
if (line.startsWith("[trust_tier:") || line.startsWith("[quoted_tool_output:") || line === "---" || line === "[SHELL RESULT CACHE]" || line === "[SHELL TRANSCRIPT]" || /^cwd_(?:before|after|note):/i.test(line) || line === "output:" || line === "stderr:" || line === "[no stderr captured]") {
|
|
575540
|
+
continue;
|
|
575541
|
+
}
|
|
575542
|
+
if (line === "stdout:" || line === "error:") {
|
|
575543
|
+
const next = lines.slice(i2 + 1).find((candidate) => candidate && candidate !== "[no stdout captured]" && candidate !== "[no stderr captured]" && candidate !== "[SHELL TRANSCRIPT]" && candidate !== "stderr:" && !/^cwd_(?:before|after|note):/i.test(candidate));
|
|
575544
|
+
if (next)
|
|
575545
|
+
push(`${line} ${next}`);
|
|
575546
|
+
continue;
|
|
575547
|
+
}
|
|
575548
|
+
if (line === "[no stdout captured]")
|
|
575549
|
+
continue;
|
|
575550
|
+
push(line);
|
|
575551
|
+
if (preview.join(" | ").length >= 520 || preview.length >= 5)
|
|
575552
|
+
break;
|
|
575553
|
+
}
|
|
575554
|
+
return preview.join(" | ").slice(0, 700);
|
|
575555
|
+
}
|
|
575488
575556
|
function actionReasonSummary(actionReason) {
|
|
575489
575557
|
if (!actionReason)
|
|
575490
575558
|
return "";
|
|
@@ -578077,6 +578145,43 @@ import { z as z17 } from "zod";
|
|
|
578077
578145
|
function cleanToolActionReasonField(value2) {
|
|
578078
578146
|
return String(value2 ?? "").replace(/\s+/g, " ").trim();
|
|
578079
578147
|
}
|
|
578148
|
+
function stripShellQuotedSegments(command) {
|
|
578149
|
+
let out = "";
|
|
578150
|
+
let quote2 = null;
|
|
578151
|
+
let escaped = false;
|
|
578152
|
+
for (let i2 = 0; i2 < command.length; i2++) {
|
|
578153
|
+
const ch = command[i2];
|
|
578154
|
+
if (quote2 === "'") {
|
|
578155
|
+
if (ch === "'")
|
|
578156
|
+
quote2 = null;
|
|
578157
|
+
out += " ";
|
|
578158
|
+
continue;
|
|
578159
|
+
}
|
|
578160
|
+
if (quote2 === '"') {
|
|
578161
|
+
if (escaped) {
|
|
578162
|
+
escaped = false;
|
|
578163
|
+
out += " ";
|
|
578164
|
+
continue;
|
|
578165
|
+
}
|
|
578166
|
+
if (ch === "\\") {
|
|
578167
|
+
escaped = true;
|
|
578168
|
+
out += " ";
|
|
578169
|
+
continue;
|
|
578170
|
+
}
|
|
578171
|
+
if (ch === '"')
|
|
578172
|
+
quote2 = null;
|
|
578173
|
+
out += " ";
|
|
578174
|
+
continue;
|
|
578175
|
+
}
|
|
578176
|
+
if (ch === "'" || ch === '"') {
|
|
578177
|
+
quote2 = ch;
|
|
578178
|
+
out += " ";
|
|
578179
|
+
continue;
|
|
578180
|
+
}
|
|
578181
|
+
out += ch;
|
|
578182
|
+
}
|
|
578183
|
+
return out;
|
|
578184
|
+
}
|
|
578080
578185
|
function parsePersistentMemoryMode(value2) {
|
|
578081
578186
|
if (value2 === "full" || value2 === "deferred" || value2 === "off")
|
|
578082
578187
|
return value2;
|
|
@@ -578768,6 +578873,7 @@ var init_agenticRunner = __esm({
|
|
|
578768
578873
|
init_completionLedger();
|
|
578769
578874
|
init_completionAutoFinalize();
|
|
578770
578875
|
init_verificationCommand();
|
|
578876
|
+
init_completionContract();
|
|
578771
578877
|
init_dist6();
|
|
578772
578878
|
init_ollama_pool();
|
|
578773
578879
|
init_personality();
|
|
@@ -579826,6 +579932,8 @@ ${parts.join("\n")}
|
|
|
579826
579932
|
lines.push(`recent_failed_approaches=${ts.failedApproaches.slice(-3).join(" | ").replace(/\s+/g, " ").slice(0, 420)}`);
|
|
579827
579933
|
}
|
|
579828
579934
|
lines.push("tool_call_contract=Mutating/side-effectful tool calls require action_reason {task_anchor,intent,evidence,expected_result,scope}; read-only evidence tools may include it but must never be blocked only for missing metadata. Compact public facts only, no hidden chain-of-thought.");
|
|
579935
|
+
lines.push("edit_transport_contract=file_edit is for exact unique current text copied from file_read; file_patch is for line-range delete/replace/insert using file_read line numbers and expected_hash/current target evidence. A failed file_edit invalidates the edit premise; rebuild from current evidence instead of broadening into file_write unless the task is truly whole-file replacement.");
|
|
579936
|
+
lines.push("range_patch_contract=If patch_ready=true or current path+start_line+end_line+expected_hash are known, call file_patch. If read_required=true or a stale exact edit lacks current range/hash, call file_read once. Do not call file_read when patch_ready=true.");
|
|
579829
579937
|
lines.push(`scope_contract=${Array.from(TOOL_ACTION_REASON_SCOPES).join("|")}; use targeted_patch for constrained code edits and full_file_rewrite only for deliberate whole-file replacement.`);
|
|
579830
579938
|
const focus = this._focusSupervisor?.snapshot().directive ?? null;
|
|
579831
579939
|
if (focus) {
|
|
@@ -580035,7 +580143,7 @@ ${parts.join("\n")}
|
|
|
580035
580143
|
temperature: options2?.temperature ?? 0,
|
|
580036
580144
|
requestTimeoutMs: options2?.requestTimeoutMs ?? 3e5,
|
|
580037
580145
|
taskTimeoutMs: options2?.taskTimeoutMs ?? 0,
|
|
580038
|
-
//
|
|
580146
|
+
// legacy health-check interval only; never a hard timeout
|
|
580039
580147
|
compactionThreshold: options2?.compactionThreshold ?? 4e4,
|
|
580040
580148
|
deepContext: options2?.deepContext ?? false,
|
|
580041
580149
|
dynamicContext: options2?.dynamicContext ?? "",
|
|
@@ -581769,8 +581877,11 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
581769
581877
|
const realFileMutation = input.realFileMutation ?? this._isRealProjectMutation(input.toolName, input.result);
|
|
581770
581878
|
const attemptedTargetPaths = this._extractToolTargetPaths(input.toolName, input.args, input.result);
|
|
581771
581879
|
const realMutationPaths = input.realMutationPaths ?? (realFileMutation ? attemptedTargetPaths : []);
|
|
581772
|
-
const
|
|
581773
|
-
const
|
|
581880
|
+
const shellActionReasonScope = input.toolName === "shell" ? input.actionReason?.scope : void 0;
|
|
581881
|
+
const shellActionReasonDeclaresVerification = shellActionReasonScope === "verification";
|
|
581882
|
+
const shellActionReasonDeclaresNonVerification = typeof shellActionReasonScope === "string" && shellActionReasonScope.length > 0 && shellActionReasonScope !== "verification";
|
|
581883
|
+
const shellVerification = input.toolName === "shell" && (shellActionReasonDeclaresVerification || !shellActionReasonDeclaresNonVerification && input.result.runtimeAuthored !== true && this._shellResultLooksLikeVerification(input.args, input.result));
|
|
581884
|
+
const shellVerificationFamily = shellVerification ? this._shellVerificationFamily(input.args, input.actionReason) : "";
|
|
581774
581885
|
if (input.result.success === true && this._isProjectEditTool(input.toolName) && !realFileMutation && input.result.alreadyApplied !== true) {
|
|
581775
581886
|
return;
|
|
581776
581887
|
}
|
|
@@ -581783,8 +581894,8 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
581783
581894
|
outputPreview: (input.outputPreview ?? this._toolEvidencePreview(input.result, void 0, 1200, input.toolName)).toString().slice(0, input.toolName === "audio_analyze" || input.toolName === "video_understand" ? 1200 : 500),
|
|
581784
581895
|
argsKey: input.argsKey.slice(0, 300),
|
|
581785
581896
|
targetPaths: attemptedTargetPaths,
|
|
581786
|
-
role: input.result.completionEvidenceRole ?? (input.result.alreadyApplied === true ? "mutation" : realFileMutation ? "mutation" : input.result.runtimeAuthored === true ? "blocker" : shellVerification ? "verification" : void 0),
|
|
581787
|
-
family: input.result.completionEvidenceFamily ?? (input.result.runtimeAuthored === true ? "runtime_control" : shellVerification ? shellVerificationFamily : void 0),
|
|
581897
|
+
role: input.result.completionEvidenceRole ?? (input.result.alreadyApplied === true ? "mutation" : realFileMutation ? "mutation" : input.result.runtimeAuthored === true && !shellVerification ? "blocker" : shellVerification ? "verification" : void 0),
|
|
581898
|
+
family: input.result.completionEvidenceFamily ?? (input.result.runtimeAuthored === true && !shellVerification ? "runtime_control" : shellVerification ? shellVerificationFamily : void 0),
|
|
581788
581899
|
verificationImpact: input.result.completionVerificationImpact ?? (input.result.alreadyApplied === true ? "neutral" : realFileMutation ? "invalidates" : void 0),
|
|
581789
581900
|
metrics: input.result.completionEvidenceMetrics
|
|
581790
581901
|
});
|
|
@@ -581804,7 +581915,17 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
581804
581915
|
}
|
|
581805
581916
|
this._saveCompletionLedgerSafe();
|
|
581806
581917
|
}
|
|
581807
|
-
_shellVerificationFamily(args) {
|
|
581918
|
+
_shellVerificationFamily(args, actionReason) {
|
|
581919
|
+
if (actionReason?.scope === "verification") {
|
|
581920
|
+
const stableParts = [
|
|
581921
|
+
actionReason.task_anchor,
|
|
581922
|
+
actionReason.expected_result
|
|
581923
|
+
].map((part) => String(part ?? "").trim()).filter(Boolean);
|
|
581924
|
+
const semanticKey = (stableParts.length > 0 ? stableParts : [String(actionReason.intent ?? "").trim()].filter(Boolean)).join(" | ");
|
|
581925
|
+
const normalized2 = normalizeCompletionKey(semanticKey || "shell verification", "shell_verification").slice(0, 140);
|
|
581926
|
+
if (normalized2)
|
|
581927
|
+
return `shell-action:${normalized2}`;
|
|
581928
|
+
}
|
|
581808
581929
|
const command = String(args?.["command"] ?? args?.["cmd"] ?? "").trim();
|
|
581809
581930
|
const normalized = normalizeShellCommand(command);
|
|
581810
581931
|
return `shell:${(normalized || command || "verification").slice(0, 160)}`;
|
|
@@ -581813,10 +581934,8 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
581813
581934
|
const command = String(args?.["command"] ?? args?.["cmd"] ?? "");
|
|
581814
581935
|
if (!command.trim())
|
|
581815
581936
|
return false;
|
|
581816
|
-
|
|
581817
|
-
|
|
581818
|
-
${result.error ?? ""}`;
|
|
581819
|
-
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(text2);
|
|
581937
|
+
void result;
|
|
581938
|
+
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);
|
|
581820
581939
|
}
|
|
581821
581940
|
_shouldSuppressCompletionDiscoveryEvidence(toolName, result, targetPaths) {
|
|
581822
581941
|
if (result.success !== true)
|
|
@@ -583757,17 +583876,18 @@ ${contentPreview}
|
|
|
583757
583876
|
const cmd = rawCmd.trim();
|
|
583758
583877
|
if (!cmd)
|
|
583759
583878
|
return false;
|
|
583760
|
-
|
|
583879
|
+
const unquoted = stripShellQuotedSegments(cmd);
|
|
583880
|
+
if (/(^|[^&\d])(>|>>)\s*\S/.test(unquoted))
|
|
583761
583881
|
return true;
|
|
583762
|
-
if (/\|\s*(?:tee|dd)\b/i.test(
|
|
583882
|
+
if (/\|\s*(?:tee|dd)\b/i.test(unquoted))
|
|
583763
583883
|
return true;
|
|
583764
|
-
if (/\b(?:sed|gsed)\s+(?:[^\n;&|]*\s)?(?:-i|--in-place)\b/i.test(
|
|
583884
|
+
if (/\b(?:sed|gsed)\s+(?:[^\n;&|]*\s)?(?:-i|--in-place)\b/i.test(unquoted))
|
|
583765
583885
|
return true;
|
|
583766
|
-
if (/\bperl\s+-[A-Za-z]*i[A-Za-z]*\b/.test(
|
|
583886
|
+
if (/\bperl\s+-[A-Za-z]*i[A-Za-z]*\b/.test(unquoted))
|
|
583767
583887
|
return true;
|
|
583768
|
-
if (/\b(?:cp|mv|rm|mkdir|rmdir|touch|truncate|ln|install|chmod|chown|chgrp|setfacl)\b/i.test(
|
|
583888
|
+
if (/\b(?:cp|mv|rm|mkdir|rmdir|touch|truncate|ln|install|chmod|chown|chgrp|setfacl)\b/i.test(unquoted))
|
|
583769
583889
|
return true;
|
|
583770
|
-
if (/\b(?:udevadm|mount|umount|modprobe|insmod)\b/i.test(
|
|
583890
|
+
if (/\b(?:udevadm|mount|umount|modprobe|insmod)\b/i.test(unquoted))
|
|
583771
583891
|
return true;
|
|
583772
583892
|
if (/\b(?:python3?|node|ruby|deno|bun)\b[\s\S]{0,240}\b(?:writeFile|writeFileSync|openSync|mkdirSync|renameSync|unlinkSync|rmSync)\b/i.test(cmd))
|
|
583773
583893
|
return true;
|
|
@@ -584227,7 +584347,7 @@ ${sections.join("\n")}` : sections.join("\n");
|
|
|
584227
584347
|
_buildRepeatCachedEvidenceNotice(toolName, args, hits, cachedResult) {
|
|
584228
584348
|
const argPreview = JSON.stringify(args ?? {}).slice(0, 200);
|
|
584229
584349
|
const target = this.extractPrimaryToolPath(args) || argPreview;
|
|
584230
|
-
const summary = this._summarizeCachedToolResult(cachedResult);
|
|
584350
|
+
const summary = this._summarizeCachedToolResult(toolName, cachedResult);
|
|
584231
584351
|
return [
|
|
584232
584352
|
"[REPEAT GATE - cached evidence not re-sent]",
|
|
584233
584353
|
`Exact repeat #${hits} of ${toolName}(${argPreview}).`,
|
|
@@ -584239,17 +584359,46 @@ ${sections.join("\n")}` : sections.join("\n");
|
|
|
584239
584359
|
"If you need different information, use a distinct offset/limit/query. For broad multi-file discovery, use file_explore, grep_search, fanout_explore, or full_sub_agent instead of repeating this call."
|
|
584240
584360
|
].join("\n");
|
|
584241
584361
|
}
|
|
584242
|
-
_summarizeCachedToolResult(output) {
|
|
584362
|
+
_summarizeCachedToolResult(toolName, output) {
|
|
584243
584363
|
const text2 = output || "";
|
|
584244
584364
|
const lineCount = text2 ? text2.split("\n").length : 0;
|
|
584245
584365
|
const sha = text2.match(/sha256=([a-f0-9]{8,64})/i)?.[1];
|
|
584246
584366
|
const header = text2.match(/\[FILE CONTEXT \|[^\]]+\]/)?.[0];
|
|
584367
|
+
const preview = toolName === "shell" ? this._meaningfulCachedShellPreview(text2) : "";
|
|
584247
584368
|
return [
|
|
584248
584369
|
`cached_size=${lineCount} lines, ${text2.length} chars`,
|
|
584249
584370
|
sha ? `cached_sha256=${sha.slice(0, 16)}` : "",
|
|
584250
|
-
header ? `cached_header=${header.slice(0, 220)}` : ""
|
|
584371
|
+
header ? `cached_header=${header.slice(0, 220)}` : "",
|
|
584372
|
+
preview ? `cached_preview=${preview}` : ""
|
|
584251
584373
|
].filter(Boolean).join("\n");
|
|
584252
584374
|
}
|
|
584375
|
+
_meaningfulCachedShellPreview(text2) {
|
|
584376
|
+
const lines = text2.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
584377
|
+
const preview = [];
|
|
584378
|
+
const push = (value2) => {
|
|
584379
|
+
if (!value2 || preview.includes(value2))
|
|
584380
|
+
return;
|
|
584381
|
+
preview.push(value2);
|
|
584382
|
+
};
|
|
584383
|
+
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
584384
|
+
const line = lines[i2];
|
|
584385
|
+
if (line.startsWith("[trust_tier:") || line.startsWith("[quoted_tool_output:") || line === "---" || line === "[SHELL RESULT CACHE]" || line === "[SHELL TRANSCRIPT]" || /^cwd_(?:before|after|note):/i.test(line) || line === "output:" || line === "stderr:" || line === "[no stderr captured]") {
|
|
584386
|
+
continue;
|
|
584387
|
+
}
|
|
584388
|
+
if (line === "stdout:" || line === "error:") {
|
|
584389
|
+
const next = lines.slice(i2 + 1).find((candidate) => candidate && candidate !== "[no stdout captured]" && candidate !== "[no stderr captured]" && candidate !== "[SHELL TRANSCRIPT]" && candidate !== "stderr:" && !/^cwd_(?:before|after|note):/i.test(candidate));
|
|
584390
|
+
if (next)
|
|
584391
|
+
push(`${line} ${next}`);
|
|
584392
|
+
continue;
|
|
584393
|
+
}
|
|
584394
|
+
if (line === "[no stdout captured]")
|
|
584395
|
+
continue;
|
|
584396
|
+
push(line);
|
|
584397
|
+
if (preview.join(" | ").length >= 520 || preview.length >= 5)
|
|
584398
|
+
break;
|
|
584399
|
+
}
|
|
584400
|
+
return preview.join(" | ").slice(0, 700);
|
|
584401
|
+
}
|
|
584253
584402
|
_renderKnowledgeBlock(recentToolResults) {
|
|
584254
584403
|
if (recentToolResults.size === 0)
|
|
584255
584404
|
return null;
|
|
@@ -586026,44 +586175,13 @@ Respond with your assessment, then take action.`;
|
|
|
586026
586175
|
}
|
|
586027
586176
|
const cleanedTask = cleanForStorage(task) || task.slice(0, 500);
|
|
586028
586177
|
const start2 = Date.now();
|
|
586029
|
-
const taskTimeoutMs = this.options.taskTimeoutMs;
|
|
586030
|
-
const hardDeadlineMs = Number.isFinite(taskTimeoutMs) && taskTimeoutMs > 0 ? start2 + taskTimeoutMs : Number.POSITIVE_INFINITY;
|
|
586031
|
-
let timedOut = false;
|
|
586032
|
-
let timeoutSummary = "";
|
|
586033
|
-
const remainingTaskMs = () => Number.isFinite(hardDeadlineMs) ? Math.max(0, hardDeadlineMs - Date.now()) : Number.POSITIVE_INFINITY;
|
|
586178
|
+
const taskTimeoutMs = Number.isFinite(this.options.taskTimeoutMs) && this.options.taskTimeoutMs > 0 ? this.options.taskTimeoutMs : Number.POSITIVE_INFINITY;
|
|
586034
586179
|
const boundedRequestTimeoutMs = () => {
|
|
586035
586180
|
const configured = Number.isFinite(this.options.requestTimeoutMs) && this.options.requestTimeoutMs > 0 ? this.options.requestTimeoutMs : 3e5;
|
|
586036
|
-
|
|
586037
|
-
return Number.isFinite(remaining) ? Math.max(1, Math.min(configured, remaining)) : configured;
|
|
586038
|
-
};
|
|
586039
|
-
const markTaskTimedOut = (phase, turn) => {
|
|
586040
|
-
if (timedOut)
|
|
586041
|
-
return;
|
|
586042
|
-
timedOut = true;
|
|
586043
|
-
timeoutSummary = `Incomplete: task timed out after ${taskTimeoutMs}ms during ${phase}.`;
|
|
586044
|
-
this.emit({
|
|
586045
|
-
type: "error",
|
|
586046
|
-
content: timeoutSummary,
|
|
586047
|
-
...typeof turn === "number" ? { turn } : {},
|
|
586048
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
586049
|
-
});
|
|
586050
|
-
this._onTypedEvent?.({
|
|
586051
|
-
type: "run_failed",
|
|
586052
|
-
runId: this._sessionId ?? "unknown",
|
|
586053
|
-
error: timeoutSummary,
|
|
586054
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
586055
|
-
});
|
|
586056
|
-
};
|
|
586057
|
-
const checkTaskTimeout = (phase, turn) => {
|
|
586058
|
-
if (!Number.isFinite(hardDeadlineMs))
|
|
586059
|
-
return false;
|
|
586060
|
-
if (Date.now() < hardDeadlineMs)
|
|
586061
|
-
return false;
|
|
586062
|
-
markTaskTimedOut(phase, turn);
|
|
586063
|
-
return true;
|
|
586181
|
+
return configured;
|
|
586064
586182
|
};
|
|
586065
586183
|
const selfEvalInterval = taskTimeoutMs;
|
|
586066
|
-
let nextSelfEval = start2 + selfEvalInterval;
|
|
586184
|
+
let nextSelfEval = Number.isFinite(selfEvalInterval) ? start2 + selfEvalInterval : Number.POSITIVE_INFINITY;
|
|
586067
586185
|
let selfEvalCount = 0;
|
|
586068
586186
|
const toolCallLog = [];
|
|
586069
586187
|
this.aborted = false;
|
|
@@ -586930,8 +587048,6 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
586930
587048
|
};
|
|
586931
587049
|
const turnCap = this.options.maxTurns && this.options.maxTurns > 0 ? this.options.maxTurns : Number.MAX_SAFE_INTEGER;
|
|
586932
587050
|
for (let turn = 0; turn < turnCap; turn++) {
|
|
586933
|
-
if (checkTaskTimeout("primary turn", turn))
|
|
586934
|
-
break;
|
|
586935
587051
|
clearTurnState(this._appState);
|
|
586936
587052
|
this._maybeApplyThinkGuard();
|
|
586937
587053
|
if (this._paused) {
|
|
@@ -588604,10 +588720,8 @@ ${memoryLines.join("\n")}`
|
|
|
588604
588720
|
break;
|
|
588605
588721
|
}
|
|
588606
588722
|
} else {
|
|
588607
|
-
const recovered = await this.retryOnTransient(reqErr, chatRequest, turn
|
|
588723
|
+
const recovered = await this.retryOnTransient(reqErr, chatRequest, turn);
|
|
588608
588724
|
if (!recovered) {
|
|
588609
|
-
if (checkTaskTimeout("backend request", turn))
|
|
588610
|
-
break;
|
|
588611
588725
|
const errMsg = reqErr instanceof Error ? reqErr.message : String(reqErr);
|
|
588612
588726
|
const cause = reqErr instanceof Error && reqErr.cause ? ` (${reqErr.cause.message ?? ""} ${reqErr.cause?.code ?? ""})` : "";
|
|
588613
588727
|
this.emit({
|
|
@@ -591591,6 +591705,7 @@ Then use file_read on individual FILES inside it.`);
|
|
|
591591
591705
|
toolName: tc.name,
|
|
591592
591706
|
argsKey: tc.arguments ? JSON.stringify(tc.arguments) : "",
|
|
591593
591707
|
args: tc.arguments,
|
|
591708
|
+
actionReason: toolActionReason,
|
|
591594
591709
|
result,
|
|
591595
591710
|
outputPreview: this._toolEvidencePreview(result, output, 1200, tc.name),
|
|
591596
591711
|
realFileMutation,
|
|
@@ -592287,9 +592402,7 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
|
|
|
592287
592402
|
}
|
|
592288
592403
|
}
|
|
592289
592404
|
let prevCycleToolCalls = toolCallCount;
|
|
592290
|
-
while (!completed && !this.aborted && !this._completionIncompleteVerification &&
|
|
592291
|
-
if (checkTaskTimeout("brute-force re-engagement"))
|
|
592292
|
-
break;
|
|
592405
|
+
while (!completed && !this.aborted && !this._completionIncompleteVerification && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles) {
|
|
592293
592406
|
bruteForceCycle++;
|
|
592294
592407
|
const totalTurns = messages2.filter((m2) => m2.role === "assistant").length;
|
|
592295
592408
|
if (bruteForceCycle > 1 && toolCallCount === prevCycleToolCalls) {
|
|
@@ -592353,8 +592466,6 @@ ${this.options.maxTurns && this.options.maxTurns > 0 ? `You have ${this.options.
|
|
|
592353
592466
|
}
|
|
592354
592467
|
const restartTurnCap = this.options.maxTurns && this.options.maxTurns > 0 ? this.options.maxTurns : Number.MAX_SAFE_INTEGER;
|
|
592355
592468
|
for (let turn = 0; turn < restartTurnCap; turn++) {
|
|
592356
|
-
if (checkTaskTimeout("brute-force turn", turn))
|
|
592357
|
-
break;
|
|
592358
592469
|
if (this._completionIncompleteVerification)
|
|
592359
592470
|
break;
|
|
592360
592471
|
this._maybeApplyThinkGuard();
|
|
@@ -592483,10 +592594,8 @@ ${this.options.maxTurns && this.options.maxTurns > 0 ? `You have ${this.options.
|
|
|
592483
592594
|
break;
|
|
592484
592595
|
}
|
|
592485
592596
|
} else {
|
|
592486
|
-
const recovered = await this.retryOnTransient(reqErr, chatRequest, turn
|
|
592597
|
+
const recovered = await this.retryOnTransient(reqErr, chatRequest, turn);
|
|
592487
592598
|
if (!recovered) {
|
|
592488
|
-
if (checkTaskTimeout("brute-force backend request", turn))
|
|
592489
|
-
break;
|
|
592490
592599
|
const errMsg2 = reqErr instanceof Error ? reqErr.message : String(reqErr);
|
|
592491
592600
|
const cause2 = reqErr instanceof Error && reqErr.cause ? ` (${reqErr.cause.message ?? ""} ${reqErr.cause?.code ?? ""})` : "";
|
|
592492
592601
|
this.emit({
|
|
@@ -592590,6 +592699,7 @@ ${this.options.maxTurns && this.options.maxTurns > 0 ? `You have ${this.options.
|
|
|
592590
592699
|
if (this.aborted)
|
|
592591
592700
|
break;
|
|
592592
592701
|
toolCallCount++;
|
|
592702
|
+
const bfActionReason = this._toolActionReasonForCall(tc.name, tc.arguments ?? {});
|
|
592593
592703
|
const bfArgsKey = this._buildExactArgsKey(tc.arguments ?? {});
|
|
592594
592704
|
toolCallLog.push({ name: tc.name, argsKey: bfArgsKey });
|
|
592595
592705
|
this._toolLastUsedTurn.set(tc.name, turn);
|
|
@@ -592734,6 +592844,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
592734
592844
|
toolName: tc.name,
|
|
592735
592845
|
argsKey: bfArgsKey,
|
|
592736
592846
|
args: tc.arguments,
|
|
592847
|
+
actionReason: bfActionReason,
|
|
592737
592848
|
result,
|
|
592738
592849
|
outputPreview: this._toolEvidencePreview(result, output, 1200, tc.name),
|
|
592739
592850
|
realFileMutation: bfRealFileMutation,
|
|
@@ -592963,9 +593074,6 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
|
|
|
592963
593074
|
}
|
|
592964
593075
|
const durationMs = Date.now() - start2;
|
|
592965
593076
|
const incompleteVerification = this._completionIncompleteVerification;
|
|
592966
|
-
if (timedOut && !summary) {
|
|
592967
|
-
summary = timeoutSummary || `Incomplete: task timed out after ${taskTimeoutMs}ms.`;
|
|
592968
|
-
}
|
|
592969
593077
|
if (incompleteVerification && !summary) {
|
|
592970
593078
|
summary = incompleteVerification.summary;
|
|
592971
593079
|
}
|
|
@@ -594512,10 +594620,11 @@ ${marker}` : marker);
|
|
|
594512
594620
|
return null;
|
|
594513
594621
|
if (process.env["OMNIUS_ALLOW_STALE_REPAIR_OVERWRITE"] === "1")
|
|
594514
594622
|
return null;
|
|
594515
|
-
if (this.options.modelTier !== "small" && this.options.modelTier !== "medium")
|
|
594516
|
-
return null;
|
|
594517
594623
|
if (args?.["dry_run"] === true || args?.["dryRun"] === true)
|
|
594518
594624
|
return null;
|
|
594625
|
+
const tier = this.options.modelTier ?? "large";
|
|
594626
|
+
if (tier !== "small" && tier !== "medium")
|
|
594627
|
+
return null;
|
|
594519
594628
|
const path12 = this.extractPrimaryToolPath(args);
|
|
594520
594629
|
if (!path12)
|
|
594521
594630
|
return null;
|
|
@@ -594529,7 +594638,7 @@ ${marker}` : marker);
|
|
|
594529
594638
|
return null;
|
|
594530
594639
|
return [
|
|
594531
594640
|
`[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"}).`,
|
|
594532
|
-
`This full-file overwrite was NOT executed. A stale narrow edit must not be repaired by broad file regeneration
|
|
594641
|
+
`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.`,
|
|
594533
594642
|
``,
|
|
594534
594643
|
`Allowed next actions:`,
|
|
594535
594644
|
`1. file_read ${active.path} once and construct file_edit from exact current text.`,
|
|
@@ -597851,6 +597960,8 @@ ${result}`
|
|
|
597851
597960
|
return true;
|
|
597852
597961
|
if (/stream timeout|no response or chunk within|no response within \d+\s*s|stream stalled/i.test(msg))
|
|
597853
597962
|
return true;
|
|
597963
|
+
if (/AbortError|operation was aborted|aborted due to timeout|signal timed out|timeout.*aborted/i.test(msg))
|
|
597964
|
+
return true;
|
|
597854
597965
|
if (/received HTML error page/i.test(msg))
|
|
597855
597966
|
return true;
|
|
597856
597967
|
if (/model is loading|server busy|overloaded/i.test(msg))
|
|
@@ -598131,11 +598242,13 @@ ${description}`
|
|
|
598131
598242
|
* until recovery; other transient backend errors use bounded backoff.
|
|
598132
598243
|
* Returns the response on success, or null if recovery did not apply.
|
|
598133
598244
|
*/
|
|
598134
|
-
async retryOnTransient(initialErr, chatRequest, turn
|
|
598245
|
+
async retryOnTransient(initialErr, chatRequest, turn) {
|
|
598246
|
+
if (this.aborted)
|
|
598247
|
+
return null;
|
|
598135
598248
|
if (!this.isTransientError(initialErr))
|
|
598136
598249
|
return null;
|
|
598137
598250
|
const errMsg = flattenErrorText(initialErr);
|
|
598138
|
-
const isNetworkError2 = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket hang up|UND_ERR|other side closed|stream timeout|no response or chunk within|no response within \d+\s*s|stream stalled/i.test(errMsg);
|
|
598251
|
+
const isNetworkError2 = /fetch failed|ECONNREFUSED|ECONNRESET|ETIMEDOUT|socket hang up|UND_ERR|other side closed|stream timeout|no response or chunk within|no response within \d+\s*s|stream stalled|AbortError|operation was aborted|aborted due to timeout|signal timed out|timeout.*aborted/i.test(errMsg);
|
|
598139
598252
|
const isAuthError = this.isRecoverableAuthError(initialErr);
|
|
598140
598253
|
const isGpuSlotUnavailable = this.isGpuSlotUnavailableError(initialErr);
|
|
598141
598254
|
const maxRetries = isNetworkError2 || isGpuSlotUnavailable || isAuthError ? Infinity : 3;
|
|
@@ -598146,15 +598259,6 @@ ${description}`
|
|
|
598146
598259
|
while (attempt <= (maxRetries === Infinity ? Number.MAX_SAFE_INTEGER : maxRetries)) {
|
|
598147
598260
|
if (this.aborted)
|
|
598148
598261
|
return null;
|
|
598149
|
-
if (Number.isFinite(hardDeadlineMs) && Date.now() >= hardDeadlineMs) {
|
|
598150
|
-
this.emit({
|
|
598151
|
-
type: "error",
|
|
598152
|
-
content: "Task timeout reached during backend retry",
|
|
598153
|
-
turn,
|
|
598154
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
598155
|
-
});
|
|
598156
|
-
return null;
|
|
598157
|
-
}
|
|
598158
598262
|
if (this.isPaymentRequiredError(initialErr) && typeof backend.rotateKey === "function") {
|
|
598159
598263
|
const rotated = backend.rotateKey();
|
|
598160
598264
|
if (rotated) {
|
|
@@ -598204,7 +598308,7 @@ ${description}`
|
|
|
598204
598308
|
}
|
|
598205
598309
|
}
|
|
598206
598310
|
const delay4 = isGpuSlotUnavailable ? baseDelayMs : Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
|
|
598207
|
-
const effectiveDelay =
|
|
598311
|
+
const effectiveDelay = delay4;
|
|
598208
598312
|
const attemptLabel = maxRetries === Infinity ? `${attempt}` : `${attempt}/${maxRetries}`;
|
|
598209
598313
|
if (isGpuSlotUnavailable) {
|
|
598210
598314
|
this.emit({
|
|
@@ -598222,15 +598326,6 @@ ${description}`
|
|
|
598222
598326
|
await new Promise((r2) => setTimeout(r2, effectiveDelay));
|
|
598223
598327
|
if (this.aborted)
|
|
598224
598328
|
return null;
|
|
598225
|
-
if (Number.isFinite(hardDeadlineMs) && Date.now() >= hardDeadlineMs) {
|
|
598226
|
-
this.emit({
|
|
598227
|
-
type: "error",
|
|
598228
|
-
content: "Task timeout reached before backend retry could resume",
|
|
598229
|
-
turn,
|
|
598230
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
598231
|
-
});
|
|
598232
|
-
return null;
|
|
598233
|
-
}
|
|
598234
598329
|
try {
|
|
598235
598330
|
this._recordContextWindowDump("agent_turn_transient_retry", chatRequest, turn, attempt);
|
|
598236
598331
|
const response = this.options.streamEnabled && this.hasStreamingSupport() ? await this.streamingRequest(chatRequest, turn) : await this.backend.chatCompletion(chatRequest);
|
|
@@ -728316,8 +728411,9 @@ function adoptHandoffRuns() {
|
|
|
728316
728411
|
} catch {
|
|
728317
728412
|
}
|
|
728318
728413
|
}
|
|
728319
|
-
|
|
728320
|
-
|
|
728414
|
+
const adoptedDeadlineAtMs = typeof r2.deadlineAtMs === "number" && r2.deadlineAtMs > 0 ? r2.deadlineAtMs : 0;
|
|
728415
|
+
if (false) {
|
|
728416
|
+
const remainingMs = adoptedDeadlineAtMs - Date.now();
|
|
728321
728417
|
const adoptedPid = r2.pid;
|
|
728322
728418
|
const adoptedJobId = r2.jobId;
|
|
728323
728419
|
const fireTimeout = () => {
|
|
@@ -728803,13 +728899,13 @@ function handleHelp(req3, res) {
|
|
|
728803
728899
|
enable: "POST /v1/chat/completions with body {agent_loop: true} runs an N-turn server-side loop. Daemon executes any tool_calls matching daemon-resident tools and re-prompts; client-side tool_calls cause the loop to yield back so caller can execute them.",
|
|
728804
728900
|
merge_daemon_tools: "Body field include_daemon_tools: ['read'] (or ['read','run']) merges the daemon's matching tools into the offered tools[] array automatically — no need to hand-list web_search/web_fetch/file_read/etc.",
|
|
728805
728901
|
max_turns: "Body field max_turns (default 8, max 64).",
|
|
728806
|
-
timeout: "Body field timeout_s
|
|
728902
|
+
timeout: "Body field timeout_s is treated as a backend/request liveness hint only; it must not kill an active agent loop.",
|
|
728807
728903
|
prompt_template: "Body field prompt_template: 'factual-first' prepends a system message instructing the model to call web_search FIRST for any factual question.",
|
|
728808
728904
|
response_envelope: "Standard OpenAI chat.completion shape PLUS a _agent_loop: {turns, log:[], done, reason} field. Reason is one of: model_returned_content, client_tools_pending, max_turns_exhausted."
|
|
728809
728905
|
},
|
|
728810
728906
|
backend_timeout: {
|
|
728811
728907
|
env: "OMNIUS_BACKEND_TIMEOUT_S — default 120 seconds, max 3600 (1 hour).",
|
|
728812
|
-
per_request: "Body field timeout_s on /v1/chat/completions, /v1/run, agent_loop
|
|
728908
|
+
per_request: "Body field timeout_s on /v1/chat/completions, /v1/run, agent_loop is request/backend liveness only, not a task deadline.",
|
|
728813
728909
|
rationale: "Q1 (Cody/SA) — was hardcoded 120s, broke cold-start tool-calling thinks on large models."
|
|
728814
728910
|
},
|
|
728815
728911
|
run_lifecycle: {
|
|
@@ -730111,32 +730207,6 @@ ${task}` : task;
|
|
|
730111
730207
|
}
|
|
730112
730208
|
};
|
|
730113
730209
|
onChildClose(child, finish);
|
|
730114
|
-
const deadline = setTimeout(
|
|
730115
|
-
() => {
|
|
730116
|
-
if (done) return;
|
|
730117
|
-
try {
|
|
730118
|
-
if (child.pid) process.kill(-child.pid, "SIGTERM");
|
|
730119
|
-
} catch {
|
|
730120
|
-
}
|
|
730121
|
-
try {
|
|
730122
|
-
if (child.pid) process.kill(child.pid, "SIGTERM");
|
|
730123
|
-
} catch {
|
|
730124
|
-
}
|
|
730125
|
-
setTimeout(() => {
|
|
730126
|
-
try {
|
|
730127
|
-
if (child.pid) process.kill(-child.pid, "SIGKILL");
|
|
730128
|
-
} catch {
|
|
730129
|
-
}
|
|
730130
|
-
try {
|
|
730131
|
-
if (child.pid) process.kill(child.pid, "SIGKILL");
|
|
730132
|
-
} catch {
|
|
730133
|
-
}
|
|
730134
|
-
finish();
|
|
730135
|
-
}, 3e3).unref();
|
|
730136
|
-
},
|
|
730137
|
-
(generateTimeoutS + 30) * 1e3
|
|
730138
|
-
);
|
|
730139
|
-
deadline.unref();
|
|
730140
730210
|
});
|
|
730141
730211
|
if (buf.trim()) finalLines.push(buf);
|
|
730142
730212
|
const rawFinal = finalLines.join("\n").trim();
|
|
@@ -730203,33 +730273,6 @@ ${task}` : task;
|
|
|
730203
730273
|
}
|
|
730204
730274
|
};
|
|
730205
730275
|
onChildClose(child, finish);
|
|
730206
|
-
const deadline = setTimeout(
|
|
730207
|
-
() => {
|
|
730208
|
-
if (done) return;
|
|
730209
|
-
killedByDeadline = true;
|
|
730210
|
-
try {
|
|
730211
|
-
if (child.pid) process.kill(-child.pid, "SIGTERM");
|
|
730212
|
-
} catch {
|
|
730213
|
-
}
|
|
730214
|
-
try {
|
|
730215
|
-
if (child.pid) process.kill(child.pid, "SIGTERM");
|
|
730216
|
-
} catch {
|
|
730217
|
-
}
|
|
730218
|
-
setTimeout(() => {
|
|
730219
|
-
try {
|
|
730220
|
-
if (child.pid) process.kill(-child.pid, "SIGKILL");
|
|
730221
|
-
} catch {
|
|
730222
|
-
}
|
|
730223
|
-
try {
|
|
730224
|
-
if (child.pid) process.kill(child.pid, "SIGKILL");
|
|
730225
|
-
} catch {
|
|
730226
|
-
}
|
|
730227
|
-
finish();
|
|
730228
|
-
}, 3e3).unref();
|
|
730229
|
-
},
|
|
730230
|
-
(generateTimeoutS + 30) * 1e3
|
|
730231
|
-
);
|
|
730232
|
-
deadline.unref();
|
|
730233
730276
|
});
|
|
730234
730277
|
if (nonStreamBuf.trim()) nonStreamLines.push(nonStreamBuf);
|
|
730235
730278
|
const rawNonStream = nonStreamLines.join("\n").trim();
|
|
@@ -730253,7 +730296,7 @@ ${task}` : task;
|
|
|
730253
730296
|
} catch {
|
|
730254
730297
|
}
|
|
730255
730298
|
if (!content) {
|
|
730256
|
-
const errMsg =
|
|
730299
|
+
const errMsg = backendError ? `Backend error: ${backendError}` : "Agent produced no response.";
|
|
730257
730300
|
jsonResponse(res, 200, {
|
|
730258
730301
|
model: model.replace(/^[a-z]+\//, ""),
|
|
730259
730302
|
created_at: createdAt,
|
|
@@ -730842,9 +730885,7 @@ async function handleV1Run(req3, res) {
|
|
|
730842
730885
|
} catch {
|
|
730843
730886
|
}
|
|
730844
730887
|
let _rca1DeadlineFired = false;
|
|
730845
|
-
const
|
|
730846
|
-
const _rca1EffectiveTimeoutS = timeout2 && timeout2 > 0 ? timeout2 : activeProfile?.limits?.timeout_s && activeProfile.limits.timeout_s > 0 ? activeProfile.limits.timeout_s : 1800;
|
|
730847
|
-
const _rca1DeadlineAtMs = Date.now() + (_rca1EffectiveTimeoutS + 60) * 1e3;
|
|
730888
|
+
const _rca1Deadline = null;
|
|
730848
730889
|
if (job.pid > 0) {
|
|
730849
730890
|
const runCtx = getOmniusRunContext();
|
|
730850
730891
|
registerProcessLease({
|
|
@@ -730859,50 +730900,9 @@ async function handleV1Run(req3, res) {
|
|
|
730859
730900
|
reason: `API run: ${task.slice(0, 240)}`,
|
|
730860
730901
|
command: sandbox === "container" ? `container:${`omnius-${id2}`}` : [process.execPath, omniusBin, ...args].join(" "),
|
|
730861
730902
|
cwd: cwd4,
|
|
730862
|
-
hardDeadlineAt:
|
|
730903
|
+
hardDeadlineAt: void 0
|
|
730863
730904
|
});
|
|
730864
730905
|
}
|
|
730865
|
-
if (!_rca1KillSwitch) {
|
|
730866
|
-
job.deadlineAtMs = _rca1DeadlineAtMs;
|
|
730867
|
-
atomicJobWrite(dir, id2, job);
|
|
730868
|
-
}
|
|
730869
|
-
const _rca1Deadline = _rca1KillSwitch ? null : setTimeout(
|
|
730870
|
-
() => {
|
|
730871
|
-
if (job.status !== "running") return;
|
|
730872
|
-
_rca1DeadlineFired = true;
|
|
730873
|
-
job.status = "timeout";
|
|
730874
|
-
job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
730875
|
-
atomicJobWrite(dir, id2, job);
|
|
730876
|
-
try {
|
|
730877
|
-
if (child.pid) process.kill(-child.pid, "SIGTERM");
|
|
730878
|
-
} catch {
|
|
730879
|
-
}
|
|
730880
|
-
try {
|
|
730881
|
-
if (child.pid) process.kill(child.pid, "SIGTERM");
|
|
730882
|
-
} catch {
|
|
730883
|
-
}
|
|
730884
|
-
setTimeout(() => {
|
|
730885
|
-
try {
|
|
730886
|
-
if (child.pid) process.kill(-child.pid, "SIGKILL");
|
|
730887
|
-
} catch {
|
|
730888
|
-
}
|
|
730889
|
-
try {
|
|
730890
|
-
if (child.pid) process.kill(child.pid, "SIGKILL");
|
|
730891
|
-
} catch {
|
|
730892
|
-
}
|
|
730893
|
-
}, 3e4).unref();
|
|
730894
|
-
try {
|
|
730895
|
-
publishEvent(
|
|
730896
|
-
"run.timeout",
|
|
730897
|
-
{ run_id: id2, deadline_s: _rca1EffectiveTimeoutS },
|
|
730898
|
-
{ subject: authUser, aimsControl: "A.6.2.6" }
|
|
730899
|
-
);
|
|
730900
|
-
} catch {
|
|
730901
|
-
}
|
|
730902
|
-
},
|
|
730903
|
-
(_rca1EffectiveTimeoutS + 60) * 1e3
|
|
730904
|
-
);
|
|
730905
|
-
if (_rca1Deadline) _rca1Deadline.unref();
|
|
730906
730906
|
if (streamMode) {
|
|
730907
730907
|
res.writeHead(200, {
|
|
730908
730908
|
"Content-Type": "text/event-stream",
|
|
@@ -733988,7 +733988,7 @@ ${historyLines}
|
|
|
733988
733988
|
reason: `chat run ${session.id}`,
|
|
733989
733989
|
command: [process.execPath, omniusBin, ...args].join(" "),
|
|
733990
733990
|
cwd: cwdPath,
|
|
733991
|
-
hardDeadlineAt:
|
|
733991
|
+
hardDeadlineAt: void 0
|
|
733992
733992
|
});
|
|
733993
733993
|
}
|
|
733994
733994
|
const releaseChatLease = (status2, reason) => {
|
|
@@ -734212,7 +734212,6 @@ ${historyLines}
|
|
|
734212
734212
|
});
|
|
734213
734213
|
child.stderr?.on("data", () => {
|
|
734214
734214
|
});
|
|
734215
|
-
const killDeadlineMs = chatTimeoutS * 1e3 + 3e4;
|
|
734216
734215
|
let killedByDeadline = false;
|
|
734217
734216
|
await new Promise((resolve77) => {
|
|
734218
734217
|
let done = false;
|
|
@@ -734223,30 +734222,6 @@ ${historyLines}
|
|
|
734223
734222
|
}
|
|
734224
734223
|
};
|
|
734225
734224
|
onChildClose(child, finish);
|
|
734226
|
-
const deadline = setTimeout(() => {
|
|
734227
|
-
if (done) return;
|
|
734228
|
-
killedByDeadline = true;
|
|
734229
|
-
try {
|
|
734230
|
-
if (child.pid) process.kill(-child.pid, "SIGTERM");
|
|
734231
|
-
} catch {
|
|
734232
|
-
}
|
|
734233
|
-
try {
|
|
734234
|
-
if (child.pid) process.kill(child.pid, "SIGTERM");
|
|
734235
|
-
} catch {
|
|
734236
|
-
}
|
|
734237
|
-
setTimeout(() => {
|
|
734238
|
-
try {
|
|
734239
|
-
if (child.pid) process.kill(-child.pid, "SIGKILL");
|
|
734240
|
-
} catch {
|
|
734241
|
-
}
|
|
734242
|
-
try {
|
|
734243
|
-
if (child.pid) process.kill(child.pid, "SIGKILL");
|
|
734244
|
-
} catch {
|
|
734245
|
-
}
|
|
734246
|
-
finish();
|
|
734247
|
-
}, 3e3).unref();
|
|
734248
|
-
}, killDeadlineMs);
|
|
734249
|
-
deadline.unref();
|
|
734250
734225
|
});
|
|
734251
734226
|
if (nonStreamBuf.trim()) nonStreamLines.push(nonStreamBuf);
|
|
734252
734227
|
const rawNonStream = nonStreamLines.join("\n").trim();
|
|
@@ -734288,7 +734263,7 @@ ${historyLines}
|
|
|
734288
734263
|
"X-Session-ID, X-Request-ID, X-API-Version, ETag"
|
|
734289
734264
|
);
|
|
734290
734265
|
if (!content) {
|
|
734291
|
-
const errMsg =
|
|
734266
|
+
const errMsg = backendError ? `Backend error: ${backendError}` : "Agent produced no response. The model may have failed to load (try a smaller model or check 'ollama ps' for VRAM contention).";
|
|
734292
734267
|
try {
|
|
734293
734268
|
finishInFlightChat(
|
|
734294
734269
|
session.id,
|
|
@@ -739711,8 +739686,6 @@ Only tools allowed by this profile are visible and executable.`
|
|
|
739711
739686
|
maxTokens: realtimeEnabled ? 512 : 16384,
|
|
739712
739687
|
temperature: realtimeEnabled ? 0.6 : 0,
|
|
739713
739688
|
requestTimeoutMs: config.timeoutMs,
|
|
739714
|
-
taskTimeoutMs: 36e5,
|
|
739715
|
-
// 60 minutes — never give up prematurely
|
|
739716
739689
|
compactionThreshold,
|
|
739717
739690
|
deepContext: deepContext ?? false,
|
|
739718
739691
|
dynamicContext,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.470",
|
|
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.470",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED