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 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 the target if more context is needed.");
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:", fencedText(input.newString));
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
- Current file content (closest match, ${pct}% similarity, lines ${snippet.startLine}–${snippet.endLine} of ${snippet.totalLines}):
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.split("\n").map((line) => line.trim()).find((line) => line.length > 0 && !line.startsWith("[trust_tier:") && line !== "---") ?? "";
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
- // 0 = no hard timeout (turn budget is the loop breaker)
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 shellVerification = input.toolName === "shell" && input.result.runtimeAuthored !== true && this._shellResultLooksLikeVerification(input.args, input.result);
581773
- const shellVerificationFamily = shellVerification ? this._shellVerificationFamily(input.args) : "";
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
- const text2 = `${command}
581817
- ${result.output ?? ""}
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
- if (/(^|[^&\d])(>|>>)\s*\S/.test(cmd))
583879
+ const unquoted = stripShellQuotedSegments(cmd);
583880
+ if (/(^|[^&\d])(>|>>)\s*\S/.test(unquoted))
583761
583881
  return true;
583762
- if (/\|\s*(?:tee|dd)\b/i.test(cmd))
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(cmd))
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(cmd))
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(cmd))
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(cmd))
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
- const remaining = remainingTaskMs();
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, hardDeadlineMs);
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 && !timedOut && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles) {
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, hardDeadlineMs);
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 on ${this.options.modelTier ?? "unknown"} tier models.`,
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, hardDeadlineMs) {
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 = Number.isFinite(hardDeadlineMs) ? Math.max(0, Math.min(delay4, hardDeadlineMs - Date.now())) : delay4;
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
- if (r2.deadlineAtMs && r2.deadlineAtMs > 0 && process.env["OMNIUS_DISABLE_DAEMON_TIMEOUT_KILL"] !== "1") {
728320
- const remainingMs = r2.deadlineAtMs - Date.now();
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 caps the whole loop (default 30 min, max 1 hour). Per-backend-call timeout is separate (see OMNIUS_BACKEND_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. Caps to 1h.",
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 = killedByDeadline ? `Agent exceeded ${generateTimeoutS}s timeout and was killed.` : backendError ? `Backend error: ${backendError}` : "Agent produced no response.";
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 _rca1KillSwitch = process.env["OMNIUS_DISABLE_DAEMON_TIMEOUT_KILL"] === "1";
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: _rca1DeadlineAtMs
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: Date.now() + chatTimeoutS * 1e3 + 3e4
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 = killedByDeadline ? `Agent exceeded ${chatTimeoutS}s timeout and was killed. Try a simpler prompt or increase timeout_s in the request body.` : 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).";
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,
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.468",
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.468",
9
+ "version": "1.0.470",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.468",
3
+ "version": "1.0.470",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",