omnius 1.0.520 → 1.0.522

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
@@ -566866,6 +566866,9 @@ var init_ollama_pool = __esm({
566866
566866
  return this.buildSlot(pick, resolvedAgentId);
566867
566867
  }
566868
566868
  if (placementMode === "constrained") {
566869
+ if (optsWithAgent.queuePolicy === "skip") {
566870
+ throw new Error("No GPU slot immediately available. All slots occupied.");
566871
+ }
566869
566872
  return this.acquireQueued(optsWithAgent, resolvedAgentId);
566870
566873
  }
566871
566874
  const spawned = placementMode === "elastic" ? await this.maybeSpawnInstance(optsWithAgent.model) : null;
@@ -566875,6 +566878,9 @@ var init_ollama_pool = __esm({
566875
566878
  this.recordAffinity(resolvedAgentId, spawned.state.id);
566876
566879
  return this.buildSlot(spawned, resolvedAgentId);
566877
566880
  }
566881
+ if (optsWithAgent.queuePolicy === "skip") {
566882
+ throw new Error("No GPU slot immediately available. All slots occupied.");
566883
+ }
566878
566884
  return this.acquireQueued(optsWithAgent, resolvedAgentId);
566879
566885
  }
566880
566886
  /** Synchronous routing decision; returns the instance or null if every one is saturated. */
@@ -566936,7 +566942,8 @@ var init_ollama_pool = __esm({
566936
566942
  return this.buildSlot(pick, agentId);
566937
566943
  }
566938
566944
  await new Promise((resolve79, reject) => {
566939
- const timer = setTimeout(() => reject(new Error("No GPU slot available after 30s. All slots occupied.")), 3e4);
566945
+ const timeoutMs = Number.isFinite(opts.queueTimeoutMs) && (opts.queueTimeoutMs ?? 0) > 0 ? Math.floor(opts.queueTimeoutMs) : 3e4;
566946
+ const timer = setTimeout(() => reject(new Error(`No GPU slot available after ${(timeoutMs / 1e3).toFixed(0)}s. All slots occupied.`)), timeoutMs);
566940
566947
  this.slotWaiters.push(() => {
566941
566948
  clearTimeout(timer);
566942
566949
  resolve79();
@@ -598799,8 +598806,14 @@ ${marker}` : marker);
598799
598806
  return { args, patchedCount: 0 };
598800
598807
  }
598801
598808
  if (toolName === "file_edit") {
598802
- if (this._normalizeExpectedHashValue(this._rawExpectedHashValue(args))) {
598803
- return { args, patchedCount: 0 };
598809
+ const currentHash = this._normalizeExpectedHashValue(this._rawExpectedHashValue(args));
598810
+ if (currentHash) {
598811
+ const path16 = this.extractPrimaryToolPath(args);
598812
+ const fresh2 = path16 ? this._freshReadHashForEditPath(path16) : null;
598813
+ if (!fresh2 || fresh2.hash === currentHash) {
598814
+ return { args, patchedCount: 0 };
598815
+ }
598816
+ return { args: { ...args, expected_hash: fresh2.hash }, patchedCount: 1 };
598804
598817
  }
598805
598818
  const path15 = this.extractPrimaryToolPath(args);
598806
598819
  const fresh = path15 ? this._freshReadHashForEditPath(path15) : null;
@@ -598826,11 +598839,15 @@ ${marker}` : marker);
598826
598839
  if (!edit || typeof edit !== "object" || Array.isArray(edit))
598827
598840
  return edit;
598828
598841
  const rec = edit;
598829
- if (this._normalizeExpectedHashValue(this._rawExpectedHashValue(rec))) {
598830
- return rec;
598831
- }
598832
598842
  const path15 = typeof rec["path"] === "string" ? rec["path"] : typeof rec["file"] === "string" ? rec["file"] : "";
598833
598843
  const fresh = path15 ? this._freshReadHashForEditPath(path15) : null;
598844
+ const currentHash = this._normalizeExpectedHashValue(this._rawExpectedHashValue(rec));
598845
+ if (currentHash) {
598846
+ if (!fresh || fresh.hash === currentHash)
598847
+ return rec;
598848
+ patchedCount++;
598849
+ return { ...rec, expected_hash: fresh.hash };
598850
+ }
598834
598851
  if (!fresh)
598835
598852
  return rec;
598836
598853
  patchedCount++;
@@ -599060,6 +599077,40 @@ ${marker}` : marker);
599060
599077
  return changed ? next : args;
599061
599078
  }
599062
599079
  _normalizeToolArgsForExecution(toolName, args) {
599080
+ if (toolName === "todo_write") {
599081
+ if (args["todos"] !== void 0)
599082
+ return args;
599083
+ const content = String(args["content"] ?? "").trim();
599084
+ if (!content)
599085
+ return args;
599086
+ const action = String(args["action"] ?? "").trim().toLowerCase();
599087
+ const rawStatus = String(args["status"] ?? "").trim();
599088
+ const status = ["pending", "in_progress", "completed", "blocked"].includes(rawStatus) ? rawStatus : action === "complete" || action === "completed" || action === "done" ? "completed" : action === "block" || action === "blocked" ? "blocked" : "in_progress";
599089
+ const todo = { content, status };
599090
+ if (typeof args["id"] === "string" && args["id"].trim()) {
599091
+ todo["id"] = args["id"].trim();
599092
+ }
599093
+ if (typeof args["parentId"] === "string" && args["parentId"].trim()) {
599094
+ todo["parentId"] = args["parentId"].trim();
599095
+ }
599096
+ const artifact = args["file"] ?? args["path"];
599097
+ if (typeof artifact === "string" && artifact.trim()) {
599098
+ todo["declaredArtifacts"] = [artifact.trim()];
599099
+ }
599100
+ if (typeof args["verifyCommand"] === "string" && args["verifyCommand"].trim()) {
599101
+ todo["verifyCommand"] = args["verifyCommand"].trim();
599102
+ }
599103
+ if (typeof args["blocker"] === "string" && args["blocker"].trim()) {
599104
+ todo["blocker"] = args["blocker"].trim();
599105
+ }
599106
+ const next2 = { todos: [todo] };
599107
+ if (typeof args["session_id"] === "string" && args["session_id"].trim()) {
599108
+ next2["session_id"] = args["session_id"].trim();
599109
+ } else if (typeof args["sessionId"] === "string" && args["sessionId"].trim()) {
599110
+ next2["session_id"] = args["sessionId"].trim();
599111
+ }
599112
+ return next2;
599113
+ }
599063
599114
  if (toolName === "working_notes") {
599064
599115
  let next2 = args;
599065
599116
  const copy2 = () => {
@@ -599218,7 +599269,7 @@ ${marker}` : marker);
599218
599269
  return [
599219
599270
  "[EDIT FRESHNESS CONTRACT]",
599220
599271
  "Exact replacement edits must be built from verified current file content, not remembered text.",
599221
- "Before file_edit or batch_edit can run, each target must carry expected_hash from file_read. If the runner has fresh read evidence, it will attach that hash automatically; otherwise the edit tool verifies the provided hash against disk before mutating.",
599272
+ "Before file_edit or batch_edit can run, each target must carry expected_hash from file_read. If the runner has fresh read evidence, it will attach or refresh that hash automatically; otherwise the edit tool verifies the provided hash against disk before mutating.",
599222
599273
  "For multiple edits to the same file, use one batch_edit against the same expected_hash so all replacements validate atomically before the file changes.",
599223
599274
  "",
599224
599275
  ...problems.map((problem) => `- ${problem}`),
@@ -603790,7 +603841,9 @@ ${description}`
603790
603841
  body["num_ctx"] = reqNumCtx;
603791
603842
  }
603792
603843
  let poolSlot = shouldUseOllamaPoolForBaseUrl(this.baseUrl) ? await getOllamaPool({ baseInstanceUrl: this.baseUrl }).acquire({
603793
- model: this.model
603844
+ model: this.model,
603845
+ queuePolicy: request.poolQueuePolicy,
603846
+ queueTimeoutMs: request.poolQueueTimeoutMs
603794
603847
  }) : null;
603795
603848
  let requestBaseUrl = poolSlot?.baseUrl ?? this.baseUrl;
603796
603849
  let poolSuccess = false;
@@ -604185,7 +604238,9 @@ ${description}`
604185
604238
  body["num_ctx"] = reqNumCtx;
604186
604239
  }
604187
604240
  let poolSlot = shouldUseOllamaPoolForBaseUrl(this.baseUrl) ? await getOllamaPool({ baseInstanceUrl: this.baseUrl }).acquire({
604188
- model: this.model
604241
+ model: this.model,
604242
+ queuePolicy: request.poolQueuePolicy,
604243
+ queueTimeoutMs: request.poolQueueTimeoutMs
604189
604244
  }) : null;
604190
604245
  let requestBaseUrl = poolSlot?.baseUrl ?? this.baseUrl;
604191
604246
  let poolSuccess = false;
@@ -686381,13 +686436,70 @@ var init_emotion_engine = __esm({
686381
686436
  this.state.arousal = BASELINE_AROUSAL + (this.state.arousal - BASELINE_AROUSAL) * decayFactor;
686382
686437
  this.state.updatedAt = Date.now();
686383
686438
  }
686439
+ emotionModelInferencePolicy() {
686440
+ const raw = process.env["OMNIUS_EMOTION_MODEL_INFERENCE"] ?? process.env["OMNIUS_EMOTION_LLM"] ?? this.config.modelInference ?? "auto";
686441
+ const value2 = String(raw).trim().toLowerCase();
686442
+ if (["0", "false", "off", "no", "disabled"].includes(value2)) {
686443
+ return "off";
686444
+ }
686445
+ if (["1", "true", "on", "yes", "enabled"].includes(value2)) {
686446
+ return "on";
686447
+ }
686448
+ return "auto";
686449
+ }
686450
+ async admitInternalInference() {
686451
+ const policy = this.emotionModelInferencePolicy();
686452
+ if (policy === "off") {
686453
+ return { allowed: false, reason: "emotion_model_inference_disabled" };
686454
+ }
686455
+ if (policy === "on") return { allowed: true };
686456
+ if (!shouldUseOllamaPoolForBaseUrl(this.config.backendUrl)) {
686457
+ return { allowed: true };
686458
+ }
686459
+ try {
686460
+ const status = await getOllamaPool({
686461
+ baseInstanceUrl: this.config.backendUrl
686462
+ }).status();
686463
+ const gpuCount = status.hardware.gpus.length;
686464
+ if (status.placement.mode === "constrained") {
686465
+ return {
686466
+ allowed: false,
686467
+ reason: `local_ollama_constrained_placement:${gpuCount}gpu`
686468
+ };
686469
+ }
686470
+ const hasImmediateSlot = status.instances.some((inst) => {
686471
+ const maxParallel = Math.max(1, inst.maxParallel);
686472
+ return inst.inflight < maxParallel;
686473
+ });
686474
+ if (!hasImmediateSlot) {
686475
+ return {
686476
+ allowed: false,
686477
+ reason: "local_ollama_no_immediate_background_slot"
686478
+ };
686479
+ }
686480
+ } catch (err) {
686481
+ const detail = err instanceof Error ? err.message : String(err);
686482
+ return {
686483
+ allowed: false,
686484
+ reason: `local_ollama_pool_status_unavailable:${detail.slice(0, 160)}`
686485
+ };
686486
+ }
686487
+ return { allowed: true };
686488
+ }
686384
686489
  async runDirectInternalInference(opts) {
686385
- const backend = new OllamaAgenticBackend(
686386
- this.config.backendUrl,
686387
- this.config.model,
686388
- this.config.apiKey,
686389
- false
686390
- );
686490
+ const cwd4 = resolve68(process.cwd());
686491
+ const startedAt2 = Date.now();
686492
+ const admission = await this.admitInternalInference();
686493
+ if (!admission.allowed) {
686494
+ this.recordInternalDecision({
686495
+ stage: opts.stage,
686496
+ status: "skipped",
686497
+ elapsedMs: Date.now() - startedAt2,
686498
+ skipReason: admission.reason,
686499
+ promptChars: opts.system.length + opts.user.length
686500
+ });
686501
+ return null;
686502
+ }
686391
686503
  const request = {
686392
686504
  messages: [
686393
686505
  { role: "system", content: opts.system },
@@ -686398,10 +686510,10 @@ var init_emotion_engine = __esm({
686398
686510
  maxTokens: opts.maxTokens,
686399
686511
  timeoutMs: opts.timeoutMs,
686400
686512
  think: false,
686401
- disableEmptyContentRecovery: true
686513
+ disableEmptyContentRecovery: true,
686514
+ poolQueuePolicy: "skip",
686515
+ poolQueueTimeoutMs: 1
686402
686516
  };
686403
- const cwd4 = resolve68(process.cwd());
686404
- const startedAt2 = Date.now();
686405
686517
  recordContextWindowDump({
686406
686518
  source: "emotionEngine",
686407
686519
  stage: opts.stage,
@@ -686416,6 +686528,12 @@ var init_emotion_engine = __esm({
686416
686528
  request
686417
686529
  });
686418
686530
  try {
686531
+ const backend = new OllamaAgenticBackend(
686532
+ this.config.backendUrl,
686533
+ this.config.model,
686534
+ this.config.apiKey,
686535
+ false
686536
+ );
686419
686537
  const result = await backend.chatCompletion(request);
686420
686538
  const output = String(
686421
686539
  result.choices?.[0]?.message?.content ?? ""
@@ -686478,6 +686596,12 @@ var init_emotion_engine = __esm({
686478
686596
  timeoutMs: 1e4,
686479
686597
  note: "best-effort emotion label refresh"
686480
686598
  });
686599
+ if (output === null) {
686600
+ this.lastLabelUpdate = Date.now();
686601
+ this.lastLabelValence = this.state.valence;
686602
+ this.lastLabelArousal = this.state.arousal;
686603
+ return;
686604
+ }
686481
686605
  const match = output.match(new RegExp("^(\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F?)\\s+(\\S+)", "u"));
686482
686606
  if (match) {
686483
686607
  this.state.emoji = match[1];
@@ -686552,6 +686676,7 @@ var init_emotion_engine = __esm({
686552
686676
  timeoutMs: 2e4,
686553
686677
  note: "best-effort Telegram admin outreach gate"
686554
686678
  });
686679
+ if (output === null) return;
686555
686680
  const message2 = this.normalizeReflectionDecision(output);
686556
686681
  if (message2) outreach(message2);
686557
686682
  } catch {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.520",
3
+ "version": "1.0.522",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.520",
9
+ "version": "1.0.522",
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.520",
3
+ "version": "1.0.522",
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",