omnius 1.0.324 → 1.0.325

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
@@ -160050,7 +160050,7 @@ var require_constants5 = __commonJS({
160050
160050
  writable: false,
160051
160051
  configurable: false
160052
160052
  };
160053
- var states = {
160053
+ var states2 = {
160054
160054
  CONNECTING: 0,
160055
160055
  OPEN: 1,
160056
160056
  CLOSING: 2,
@@ -160086,7 +160086,7 @@ var require_constants5 = __commonJS({
160086
160086
  uid,
160087
160087
  sentCloseFrameState,
160088
160088
  staticPropertyDescriptors,
160089
- states,
160089
+ states: states2,
160090
160090
  opcodes,
160091
160091
  maxUnsigned16Bit,
160092
160092
  parserStates,
@@ -160100,21 +160100,21 @@ var require_constants5 = __commonJS({
160100
160100
  var require_util7 = __commonJS({
160101
160101
  "../node_modules/undici/lib/web/websocket/util.js"(exports, module) {
160102
160102
  "use strict";
160103
- var { states, opcodes } = require_constants5();
160103
+ var { states: states2, opcodes } = require_constants5();
160104
160104
  var { isUtf8 } = __require("node:buffer");
160105
160105
  var { removeHTTPWhitespace } = require_data_url();
160106
160106
  var { collectASequenceOfCodePointsFast } = require_infra();
160107
160107
  function isConnecting(readyState) {
160108
- return readyState === states.CONNECTING;
160108
+ return readyState === states2.CONNECTING;
160109
160109
  }
160110
160110
  function isEstablished(readyState) {
160111
- return readyState === states.OPEN;
160111
+ return readyState === states2.OPEN;
160112
160112
  }
160113
160113
  function isClosing(readyState) {
160114
- return readyState === states.CLOSING;
160114
+ return readyState === states2.CLOSING;
160115
160115
  }
160116
160116
  function isClosed(readyState) {
160117
- return readyState === states.CLOSED;
160117
+ return readyState === states2.CLOSED;
160118
160118
  }
160119
160119
  function fireEvent(e2, target, eventFactory = (type, init2) => new Event(type, init2), eventInitDict = {}) {
160120
160120
  const event = eventFactory(e2, eventInitDict);
@@ -160382,7 +160382,7 @@ var require_frame = __commonJS({
160382
160382
  var require_connection = __commonJS({
160383
160383
  "../node_modules/undici/lib/web/websocket/connection.js"(exports, module) {
160384
160384
  "use strict";
160385
- var { uid, states, sentCloseFrameState, emptyBuffer, opcodes } = require_constants5();
160385
+ var { uid, states: states2, sentCloseFrameState, emptyBuffer, opcodes } = require_constants5();
160386
160386
  var { parseExtensions, isClosed, isClosing, isEstablished, isConnecting, validateCloseCodeAndReason } = require_util7();
160387
160387
  var { makeRequest } = require_request2();
160388
160388
  var { fetching } = require_fetch();
@@ -160489,7 +160489,7 @@ var require_connection = __commonJS({
160489
160489
  if (isClosed(object.readyState) || isClosing(object.readyState)) {
160490
160490
  } else if (!isEstablished(object.readyState)) {
160491
160491
  failWebsocketConnection(object);
160492
- object.readyState = states.CLOSING;
160492
+ object.readyState = states2.CLOSING;
160493
160493
  } else if (!object.closeState.has(sentCloseFrameState.SENT) && !object.closeState.has(sentCloseFrameState.RECEIVED)) {
160494
160494
  const frame = new WebsocketFrameSend();
160495
160495
  if (reason.length !== 0 && code8 === null) {
@@ -160510,9 +160510,9 @@ var require_connection = __commonJS({
160510
160510
  }
160511
160511
  object.socket.write(frame.createFrame(opcodes.CLOSE));
160512
160512
  object.closeState.add(sentCloseFrameState.SENT);
160513
- object.readyState = states.CLOSING;
160513
+ object.readyState = states2.CLOSING;
160514
160514
  } else {
160515
- object.readyState = states.CLOSING;
160515
+ object.readyState = states2.CLOSING;
160516
160516
  }
160517
160517
  }
160518
160518
  function failWebsocketConnection(handler, code8, reason, cause) {
@@ -160633,7 +160633,7 @@ var require_receiver = __commonJS({
160633
160633
  "use strict";
160634
160634
  var { Writable } = __require("node:stream");
160635
160635
  var assert = __require("node:assert");
160636
- var { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = require_constants5();
160636
+ var { parserStates, opcodes, states: states2, emptyBuffer, sentCloseFrameState } = require_constants5();
160637
160637
  var {
160638
160638
  isValidStatusCode,
160639
160639
  isValidOpcode,
@@ -160921,7 +160921,7 @@ var require_receiver = __commonJS({
160921
160921
  this.#handler.socket.write(closeFrame.createFrame(opcodes.CLOSE));
160922
160922
  this.#handler.closeState.add(sentCloseFrameState.SENT);
160923
160923
  }
160924
- this.#handler.readyState = states.CLOSING;
160924
+ this.#handler.readyState = states2.CLOSING;
160925
160925
  this.#handler.closeState.add(sentCloseFrameState.RECEIVED);
160926
160926
  return false;
160927
160927
  } else if (opcode === opcodes.PING) {
@@ -161040,7 +161040,7 @@ var require_websocket = __commonJS({
161040
161040
  var { webidl } = require_webidl();
161041
161041
  var { URLSerializer } = require_data_url();
161042
161042
  var { environmentSettingsObject } = require_util4();
161043
- var { staticPropertyDescriptors, states, sentCloseFrameState, sendHints, opcodes } = require_constants5();
161043
+ var { staticPropertyDescriptors, states: states2, sentCloseFrameState, sendHints, opcodes } = require_constants5();
161044
161044
  var {
161045
161045
  isConnecting,
161046
161046
  isEstablished,
@@ -161093,7 +161093,7 @@ var require_websocket = __commonJS({
161093
161093
  }
161094
161094
  },
161095
161095
  onSocketError: (err) => {
161096
- this.#handler.readyState = states.CLOSING;
161096
+ this.#handler.readyState = states2.CLOSING;
161097
161097
  if (channels.socketError.hasSubscribers) {
161098
161098
  channels.socketError.publish(err);
161099
161099
  }
@@ -161116,7 +161116,7 @@ var require_websocket = __commonJS({
161116
161116
  });
161117
161117
  }
161118
161118
  },
161119
- readyState: states.CONNECTING,
161119
+ readyState: states2.CONNECTING,
161120
161120
  socket: null,
161121
161121
  closeState: /* @__PURE__ */ new Set(),
161122
161122
  controller: null,
@@ -161327,7 +161327,7 @@ var require_websocket = __commonJS({
161327
161327
  parser2.on("error", (err) => this.#handler.onParserError(err));
161328
161328
  this.#parser = parser2;
161329
161329
  this.#sendQueue = new SendQueue(response.socket);
161330
- this.#handler.readyState = states.OPEN;
161330
+ this.#handler.readyState = states2.OPEN;
161331
161331
  const extensions = response.headersList.get("sec-websocket-extensions");
161332
161332
  if (extensions !== null) {
161333
161333
  this.#extensions = extensions;
@@ -161353,7 +161353,7 @@ var require_websocket = __commonJS({
161353
161353
  }
161354
161354
  }
161355
161355
  #onMessage(type, data) {
161356
- if (this.#handler.readyState !== states.OPEN) {
161356
+ if (this.#handler.readyState !== states2.OPEN) {
161357
161357
  return;
161358
161358
  }
161359
161359
  let dataForEvent;
@@ -161392,7 +161392,7 @@ var require_websocket = __commonJS({
161392
161392
  code8 = result.code ?? 1005;
161393
161393
  reason = result.reason;
161394
161394
  }
161395
- this.#handler.readyState = states.CLOSED;
161395
+ this.#handler.readyState = states2.CLOSED;
161396
161396
  if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
161397
161397
  code8 = 1006;
161398
161398
  fireEvent("error", this, (type, init2) => new ErrorEvent2(type, init2), {
@@ -161433,10 +161433,10 @@ var require_websocket = __commonJS({
161433
161433
  };
161434
161434
  var { ping: ping2 } = WebSocket6;
161435
161435
  Reflect.deleteProperty(WebSocket6, "ping");
161436
- WebSocket6.CONNECTING = WebSocket6.prototype.CONNECTING = states.CONNECTING;
161437
- WebSocket6.OPEN = WebSocket6.prototype.OPEN = states.OPEN;
161438
- WebSocket6.CLOSING = WebSocket6.prototype.CLOSING = states.CLOSING;
161439
- WebSocket6.CLOSED = WebSocket6.prototype.CLOSED = states.CLOSED;
161436
+ WebSocket6.CONNECTING = WebSocket6.prototype.CONNECTING = states2.CONNECTING;
161437
+ WebSocket6.OPEN = WebSocket6.prototype.OPEN = states2.OPEN;
161438
+ WebSocket6.CLOSING = WebSocket6.prototype.CLOSING = states2.CLOSING;
161439
+ WebSocket6.CLOSED = WebSocket6.prototype.CLOSED = states2.CLOSED;
161440
161440
  Object.defineProperties(WebSocket6.prototype, {
161441
161441
  CONNECTING: staticPropertyDescriptors,
161442
161442
  OPEN: staticPropertyDescriptors,
@@ -161602,7 +161602,7 @@ var require_websocketstream = __commonJS({
161602
161602
  "use strict";
161603
161603
  var { createDeferredPromise: createDeferredPromise2 } = require_promise();
161604
161604
  var { environmentSettingsObject } = require_util4();
161605
- var { states, opcodes, sentCloseFrameState } = require_constants5();
161605
+ var { states: states2, opcodes, sentCloseFrameState } = require_constants5();
161606
161606
  var { webidl } = require_webidl();
161607
161607
  var { getURLRecord, isValidSubprotocol, isEstablished, utf8Decode } = require_util7();
161608
161608
  var { establishWebSocketConnection, failWebsocketConnection, closeWebSocketConnection } = require_connection();
@@ -161646,7 +161646,7 @@ var require_websocketstream = __commonJS({
161646
161646
  }
161647
161647
  },
161648
161648
  onSocketError: (err) => {
161649
- this.#handler.readyState = states.CLOSING;
161649
+ this.#handler.readyState = states2.CLOSING;
161650
161650
  if (channels.socketError.hasSubscribers) {
161651
161651
  channels.socketError.publish(err);
161652
161652
  }
@@ -161657,7 +161657,7 @@ var require_websocketstream = __commonJS({
161657
161657
  },
161658
161658
  onPong: () => {
161659
161659
  },
161660
- readyState: states.CONNECTING,
161660
+ readyState: states2.CONNECTING,
161661
161661
  socket: null,
161662
161662
  closeState: /* @__PURE__ */ new Set(),
161663
161663
  controller: null,
@@ -161699,7 +161699,7 @@ var require_websocketstream = __commonJS({
161699
161699
  signal.addEventListener("abort", () => {
161700
161700
  if (!isEstablished(this.#handler.readyState)) {
161701
161701
  failWebsocketConnection(this.#handler);
161702
- this.#handler.readyState = states.CLOSING;
161702
+ this.#handler.readyState = states2.CLOSING;
161703
161703
  this.#openedPromise.reject(signal.reason);
161704
161704
  this.#closedPromise.reject(signal.reason);
161705
161705
  this.#handshakeAborted = true;
@@ -161770,7 +161770,7 @@ var require_websocketstream = __commonJS({
161770
161770
  parser2.on("drain", () => this.#handler.onParserDrain());
161771
161771
  parser2.on("error", (err) => this.#handler.onParserError(err));
161772
161772
  this.#parser = parser2;
161773
- this.#handler.readyState = states.OPEN;
161773
+ this.#handler.readyState = states2.OPEN;
161774
161774
  const extensions = parsedExtensions ?? "";
161775
161775
  const protocol = response.headersList.get("sec-websocket-protocol") ?? "";
161776
161776
  const readable = new ReadableStream({
@@ -161801,7 +161801,7 @@ var require_websocketstream = __commonJS({
161801
161801
  }
161802
161802
  /** @type {import('../websocket').Handler['onMessage']} */
161803
161803
  #onMessage(type, data) {
161804
- if (this.#handler.readyState !== states.OPEN) {
161804
+ if (this.#handler.readyState !== states2.OPEN) {
161805
161805
  return;
161806
161806
  }
161807
161807
  let chunk;
@@ -161820,7 +161820,7 @@ var require_websocketstream = __commonJS({
161820
161820
  /** @type {import('../websocket').Handler['onSocketClose']} */
161821
161821
  #onSocketClose() {
161822
161822
  const wasClean = this.#handler.closeState.has(sentCloseFrameState.SENT) && this.#handler.closeState.has(sentCloseFrameState.RECEIVED);
161823
- this.#handler.readyState = states.CLOSED;
161823
+ this.#handler.readyState = states2.CLOSED;
161824
161824
  if (this.#handshakeAborted) {
161825
161825
  return;
161826
161826
  }
@@ -563637,11 +563637,11 @@ var init_streaming_executor = __esm({
563637
563637
  }
563638
563638
  /** Get the current state of all tool calls */
563639
563639
  getStates() {
563640
- const states = /* @__PURE__ */ new Map();
563640
+ const states2 = /* @__PURE__ */ new Map();
563641
563641
  for (const [id, entry] of this.tools) {
563642
- states.set(id, entry.state);
563642
+ states2.set(id, entry.state);
563643
563643
  }
563644
- return states;
563644
+ return states2;
563645
563645
  }
563646
563646
  /** Get count of tools in each state */
563647
563647
  getCounts() {
@@ -596660,10 +596660,61 @@ var init_secret_redactor = __esm({
596660
596660
  }
596661
596661
  });
596662
596662
 
596663
+ // packages/cli/src/tui/tool-collapse-store.ts
596664
+ function isCollapsibleBlock(id) {
596665
+ return states.has(id);
596666
+ }
596667
+ function ensureCollapsible(id) {
596668
+ let s2 = states.get(id);
596669
+ if (s2 === void 0) {
596670
+ s2 = globalDefault;
596671
+ states.set(id, s2);
596672
+ }
596673
+ return s2;
596674
+ }
596675
+ function getCollapseState(id) {
596676
+ return states.get(id) ?? globalDefault;
596677
+ }
596678
+ function setCollapseState(id, state) {
596679
+ states.set(id, state);
596680
+ }
596681
+ function toggleTitle(id) {
596682
+ const cur = getCollapseState(id);
596683
+ setCollapseState(id, cur === "collapsed" ? "preview" : "collapsed");
596684
+ }
596685
+ function toggleMore(id) {
596686
+ const cur = getCollapseState(id);
596687
+ setCollapseState(id, cur === "expanded" ? "preview" : "expanded");
596688
+ }
596689
+ function toggleAll() {
596690
+ let anyOpen = false;
596691
+ for (const s2 of states.values()) {
596692
+ if (s2 !== "collapsed") {
596693
+ anyOpen = true;
596694
+ break;
596695
+ }
596696
+ }
596697
+ const next = anyOpen ? "collapsed" : "preview";
596698
+ for (const id of states.keys()) states.set(id, next);
596699
+ globalDefault = next;
596700
+ }
596701
+ var PREVIEW_ROWS, READ_MORE_LABEL, READ_LESS_LABEL, globalDefault, states;
596702
+ var init_tool_collapse_store = __esm({
596703
+ "packages/cli/src/tui/tool-collapse-store.ts"() {
596704
+ "use strict";
596705
+ PREVIEW_ROWS = 8;
596706
+ READ_MORE_LABEL = "read more…";
596707
+ READ_LESS_LABEL = "read less";
596708
+ globalDefault = "preview";
596709
+ states = /* @__PURE__ */ new Map();
596710
+ }
596711
+ });
596712
+
596663
596713
  // packages/cli/src/tui/render.ts
596664
596714
  var render_exports = {};
596665
596715
  __export(render_exports, {
596666
596716
  SLASH_COMMANDS: () => SLASH_COMMANDS2,
596717
+ applyCollapseToBox: () => applyCollapseToBox,
596667
596718
  breakTelegramCoalesce: () => breakTelegramCoalesce,
596668
596719
  c: () => c3,
596669
596720
  charWidth: () => charWidth2,
@@ -597088,6 +597139,52 @@ function buildToolBottom(width, colorCode) {
597088
597139
  const border = toolColorSeq(colorCode);
597089
597140
  return `${border}${BOX_BL2}${BOX_H2.repeat(Math.max(0, width - 2))}${BOX_BR2}${toolResetSeq()}`;
597090
597141
  }
597142
+ function dimSeqOrEmpty() {
597143
+ return _colorsEnabled && stdoutIsTTY() ? "\x1B[2m" : "";
597144
+ }
597145
+ function underlineSeqOrEmpty() {
597146
+ return _colorsEnabled && stdoutIsTTY() ? "\x1B[4m" : "";
597147
+ }
597148
+ function collapsedBarLine(desc) {
597149
+ const seq = toolColorSeq(desc.colorCode);
597150
+ const reset = toolResetSeq();
597151
+ const dim = dimSeqOrEmpty();
597152
+ const title = sanitizeToolBoxContent(desc.title);
597153
+ const metrics2 = desc.metrics ? ` ${dim}${sanitizeToolBoxContent(desc.metrics)}${reset}` : "";
597154
+ return `${seq}▸ ${title}${reset}${metrics2}`;
597155
+ }
597156
+ function affordanceRowText(label, hiddenRows) {
597157
+ const ul = underlineSeqOrEmpty();
597158
+ const dim = dimSeqOrEmpty();
597159
+ const reset = toolResetSeq();
597160
+ const suffix = hiddenRows && hiddenRows > 0 ? `${dim} (${hiddenRows} more line${hiddenRows === 1 ? "" : "s"})${reset}` : "";
597161
+ return `${ul}${label}${reset}${suffix}`;
597162
+ }
597163
+ function applyCollapseToBox(fullLines, opts) {
597164
+ if (fullLines.length === 0) return fullLines;
597165
+ if (opts.state === "collapsed") return [collapsedBarLine(opts.desc)];
597166
+ if (fullLines.length < 4) return fullLines;
597167
+ const w = Math.max(40, opts.width);
597168
+ const head = fullLines.slice(0, 2);
597169
+ const bottom = fullLines[fullLines.length - 1];
597170
+ const body = fullLines.slice(2, fullLines.length - 1);
597171
+ if (body.length <= PREVIEW_ROWS) return fullLines;
597172
+ if (opts.state === "preview") {
597173
+ const shown = body.slice(0, PREVIEW_ROWS);
597174
+ const moreRow = buildToolContentRow(
597175
+ affordanceRowText(READ_MORE_LABEL, body.length - PREVIEW_ROWS),
597176
+ w,
597177
+ opts.desc.colorCode
597178
+ );
597179
+ return [...head, ...shown, moreRow, bottom];
597180
+ }
597181
+ const lessRow = buildToolContentRow(
597182
+ affordanceRowText(READ_LESS_LABEL),
597183
+ w,
597184
+ opts.desc.colorCode
597185
+ );
597186
+ return [...head, ...body, lessRow, bottom];
597187
+ }
597091
597188
  function buildToolContentRow(content, width, colorCode) {
597092
597189
  const border = toolColorSeq(colorCode);
597093
597190
  const reset = toolResetSeq();
@@ -597330,12 +597427,24 @@ function buildToolBoxLines(data, width) {
597330
597427
  lines.push(buildToolBottom(w, data.colorCode));
597331
597428
  return lines;
597332
597429
  }
597333
- function renderToolDynamicBlock(kind, render2, opts) {
597430
+ function renderToolDynamicBlock(kind, render2, opts, collapse) {
597334
597431
  const redir = _contentWriteHook?.redirect?.();
597335
597432
  const host = opts.host !== void 0 ? opts.host : _contentWriteHook?.dynamicBlockHost?.();
597336
597433
  if (!redir && host) {
597337
597434
  const id = `${kind}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
597338
- host.registerDynamicBlock(id, render2);
597435
+ if (collapse) {
597436
+ ensureCollapsible(id);
597437
+ host.registerDynamicBlock(
597438
+ id,
597439
+ (width) => applyCollapseToBox(render2(width), {
597440
+ state: getCollapseState(id),
597441
+ desc: collapse,
597442
+ width
597443
+ })
597444
+ );
597445
+ } else {
597446
+ host.registerDynamicBlock(id, render2);
597447
+ }
597339
597448
  host.appendDynamicBlock(id);
597340
597449
  return;
597341
597450
  }
@@ -597800,10 +597909,32 @@ function renderToolLine(content, isLast = false) {
597800
597909
  process.stdout.write(`${lines.join("\n")}
597801
597910
  `);
597802
597911
  }
597912
+ function toolResultCollapseDescriptor(toolName, success, output, opts) {
597913
+ const label = TOOL_LABELS[toolName] ?? toolName;
597914
+ const status = success ? "✔" : "✖";
597915
+ const rawLines = output.split("\n").filter((line) => line.trim()).length;
597916
+ const metrics2 = [
597917
+ success ? "ok" : "failed",
597918
+ rawLines > 0 ? `${rawLines} line${rawLines === 1 ? "" : "s"}` : "",
597919
+ output.length > 0 ? `${output.length.toLocaleString()} chars` : "",
597920
+ opts.durationMs && opts.durationMs > 0 ? formatDuration4(opts.durationMs) : ""
597921
+ ].filter(Boolean).join(" · ");
597922
+ return {
597923
+ title: `${status} ${label}`,
597924
+ metrics: metrics2,
597925
+ colorCode: success ? toolColorCode(toolName) : TOOL_ERROR_COLOR_CODE
597926
+ };
597927
+ }
597803
597928
  function renderToolResult(toolName, success, output, verboseOrOpts) {
597804
597929
  breakTelegramCoalesce();
597805
597930
  const opts = normalizeToolOpts(verboseOrOpts);
597806
597931
  const frozenOutput = getSecretRedactor().redactText(String(output ?? ""));
597932
+ const collapseDesc = toolResultCollapseDescriptor(
597933
+ toolName,
597934
+ success,
597935
+ frozenOutput,
597936
+ opts
597937
+ );
597807
597938
  if (_pendingToolCall && _pendingToolCall.toolName === toolName) {
597808
597939
  const pending2 = _pendingToolCall;
597809
597940
  _pendingToolCall = null;
@@ -597817,7 +597948,8 @@ function renderToolResult(toolName, success, output, verboseOrOpts) {
597817
597948
  { ...opts, verbose: pending2.verbose ?? opts.verbose },
597818
597949
  width
597819
597950
  ),
597820
- opts
597951
+ opts,
597952
+ collapseDesc
597821
597953
  );
597822
597954
  return;
597823
597955
  }
@@ -597825,7 +597957,8 @@ function renderToolResult(toolName, success, output, verboseOrOpts) {
597825
597957
  renderToolDynamicBlock(
597826
597958
  "tool-result",
597827
597959
  (width) => buildToolResultBoxLines(toolName, success, frozenOutput, opts, width),
597828
- opts
597960
+ opts,
597961
+ collapseDesc
597829
597962
  );
597830
597963
  }
597831
597964
  function renderBoxedBlock(opts) {
@@ -598248,6 +598381,7 @@ var init_render = __esm({
598248
598381
  init_syntax_highlight();
598249
598382
  init_model_picker();
598250
598383
  init_secret_redactor();
598384
+ init_tool_collapse_store();
598251
598385
  c3 = {
598252
598386
  bold: (t2) => ansi2("1", t2),
598253
598387
  dim: (t2) => stdoutIsTTY() ? `${dimFg()}${t2}\x1B[0m` : t2,
@@ -607576,6 +607710,7 @@ var init_status_bar = __esm({
607576
607710
  init_overlay_lock();
607577
607711
  init_dist5();
607578
607712
  init_theme();
607713
+ init_tool_collapse_store();
607579
607714
  init_layout2();
607580
607715
  EXPERT_TOOL_BASELINES = {
607581
607716
  file_read: 12,
@@ -607807,6 +607942,11 @@ var init_status_bar = __esm({
607807
607942
  _contentScrollOffset = 0;
607808
607943
  // 0 = live (bottom), >0 = scrolled back
607809
607944
  _contentMaxLines = 1e4;
607945
+ // Snapshot of the most recent content paint, used to map a mouse-click screen
607946
+ // row back to the reflowed line (and thus its dynamic-block id) for click
607947
+ // hit-testing on collapsible tool boxes. Refreshed on every repaintContent().
607948
+ _lastPaintReflow = null;
607949
+ _lastPaintStartIdx = 0;
607810
607950
  /**
607811
607951
  * Dynamic content blocks — width-aware regions that re-render themselves
607812
607952
  * when the terminal resizes. The renderer registered here is called from
@@ -609513,6 +609653,55 @@ var init_status_bar = __esm({
609513
609653
  get textSelection() {
609514
609654
  return this._textSelection;
609515
609655
  }
609656
+ /**
609657
+ * Map a screen row to the collapsible tool box painted there (if any). Uses
609658
+ * the snapshot captured during the last repaintContent(): screen row r shows
609659
+ * reflowedLines[startIdx + (r - scrollRegionTop)]. All reflowed rows of a
609660
+ * dynamic block share the sentinel's bufferIdx, so we can recover the block
609661
+ * id and the row's offset within the block.
609662
+ */
609663
+ hitTestContentBlock(screenRow) {
609664
+ const reflow = this._lastPaintReflow;
609665
+ if (!reflow) return null;
609666
+ const rel = screenRow - this.scrollRegionTop;
609667
+ if (rel < 0) return null;
609668
+ const idx = this._lastPaintStartIdx + rel;
609669
+ const entry = reflow[idx];
609670
+ if (!entry) return null;
609671
+ const src2 = this._contentLines[entry.bufferIdx];
609672
+ if (!src2 || !src2.startsWith(this.DYNAMIC_BLOCK_MARK_PREFIX) || !src2.endsWith(this.DYNAMIC_BLOCK_MARK_SUFFIX)) {
609673
+ return null;
609674
+ }
609675
+ const id = src2.slice(
609676
+ this.DYNAMIC_BLOCK_MARK_PREFIX.length,
609677
+ src2.length - this.DYNAMIC_BLOCK_MARK_SUFFIX.length
609678
+ );
609679
+ let first2 = idx;
609680
+ while (first2 > 0 && reflow[first2 - 1]?.bufferIdx === entry.bufferIdx) {
609681
+ first2--;
609682
+ }
609683
+ return { id, offset: idx - first2, lineText: entry.line };
609684
+ }
609685
+ /**
609686
+ * Handle a click inside a collapsible tool box. Title row (offset 0) toggles
609687
+ * collapsed↔preview; a "read more…/read less" row toggles preview↔expanded;
609688
+ * other body rows are left alone so text selection still works. Returns true
609689
+ * when the click was consumed.
609690
+ */
609691
+ handleContentBlockClick(screenRow) {
609692
+ const hit = this.hitTestContentBlock(screenRow);
609693
+ if (!hit || !isCollapsibleBlock(hit.id)) return false;
609694
+ const plain = stripAnsi(hit.lineText);
609695
+ if (plain.includes(READ_MORE_LABEL) || plain.includes(READ_LESS_LABEL)) {
609696
+ toggleMore(hit.id);
609697
+ } else if (hit.offset === 0) {
609698
+ toggleTitle(hit.id);
609699
+ } else {
609700
+ return false;
609701
+ }
609702
+ this.refreshDynamicBlocks();
609703
+ return true;
609704
+ }
609516
609705
  /**
609517
609706
  * Handle a mouse pointer event (press/drag/release).
609518
609707
  * Called by MouseFilterStream's pointer handler.
@@ -609522,6 +609711,9 @@ var init_status_bar = __esm({
609522
609711
  handlePointerEvent(type, col, row) {
609523
609712
  if (!this.active) return;
609524
609713
  const w = termCols();
609714
+ if (type === "press" && row >= this.scrollRegionTop) {
609715
+ if (this.handleContentBlockClick(row)) return;
609716
+ }
609525
609717
  if (type === "press" && this._suggestions.length > 0) {
609526
609718
  if (this.suggestClickAt(row)) return;
609527
609719
  }
@@ -610174,6 +610366,20 @@ ${CONTENT_BG_SEQ}`);
610174
610366
  this.repaintContent();
610175
610367
  this.renderFooterAndPositionInput();
610176
610368
  }
610369
+ /**
610370
+ * Flicker-free in-place repaint of the content area (and thus any dynamic
610371
+ * blocks within it). Unlike refreshDisplay(), this does NOT blank the area
610372
+ * first via fillContentArea() — repaintContent() uses synchronized output
610373
+ * (\x1B[?2026h) and a per-row \x1B[2K clear, so a live block that updates
610374
+ * many times per second (e.g. the shell timer) refreshes without the whole
610375
+ * TUI flashing. Implements the DynamicBlockHost.refreshDynamicBlocks contract.
610376
+ */
610377
+ refreshDynamicBlocks() {
610378
+ if (!this.active) return;
610379
+ if (this._contentScrollOffset > 0 || this._mouseSelecting) return;
610380
+ if (isOverlayActive() || this._suspendContentLayer) return;
610381
+ this.repaintContent();
610382
+ }
610177
610383
  clearStreamingRepaintTimer() {
610178
610384
  if (!this._streamingRepaintTimer) return;
610179
610385
  clearTimeout(this._streamingRepaintTimer);
@@ -610552,6 +610758,8 @@ ${CONTENT_BG_SEQ}`);
610552
610758
  if (this._contentScrollOffset === 0) this._autoScroll = true;
610553
610759
  }
610554
610760
  const startIdx = Math.max(0, totalLines - h - this._contentScrollOffset);
610761
+ this._lastPaintReflow = reflowedLines;
610762
+ this._lastPaintStartIdx = startIdx;
610555
610763
  const headerSafeFloor = layout().headerBottom + 1;
610556
610764
  let buf = "\x1B[?2026h";
610557
610765
  buf += "\x1B7";
@@ -653287,8 +653495,8 @@ var init_telegram_stats_menu = __esm({
653287
653495
  INACTIVITY_TIMEOUT_MS2 = 6e4;
653288
653496
  COUNTDOWN_SECONDS2 = 10;
653289
653497
  StatsMenuTimerManager = class {
653290
- constructor(states, callbacks, getSnapshot) {
653291
- this.states = states;
653498
+ constructor(states2, callbacks, getSnapshot) {
653499
+ this.states = states2;
653292
653500
  this.callbacks = callbacks;
653293
653501
  this.getSnapshot = getSnapshot;
653294
653502
  }
@@ -668271,9 +668479,9 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`
668271
668479
  }
668272
668480
  createTelegramGenerativeProgressBridge(chatId, msg) {
668273
668481
  if (chatId === void 0) return void 0;
668274
- const states = /* @__PURE__ */ new Map();
668482
+ const states2 = /* @__PURE__ */ new Map();
668275
668483
  const stateFor = (toolName) => {
668276
- let state = states.get(toolName);
668484
+ let state = states2.get(toolName);
668277
668485
  if (!state) {
668278
668486
  state = {
668279
668487
  messageId: null,
@@ -668281,7 +668489,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`
668281
668489
  queuedHtml: null,
668282
668490
  lastRenderedAt: 0
668283
668491
  };
668284
- states.set(toolName, state);
668492
+ states2.set(toolName, state);
668285
668493
  }
668286
668494
  return state;
668287
668495
  };
@@ -668354,7 +668562,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`
668354
668562
  },
668355
668563
  complete: (toolName, result) => {
668356
668564
  if (!generationKindForToolName(toolName)) return;
668357
- const state = states.get(toolName);
668565
+ const state = states2.get(toolName);
668358
668566
  if (!state && result.success) return;
668359
668567
  const html = completeHtml(toolName, result);
668360
668568
  if (!html) return;
@@ -675739,6 +675947,10 @@ function finishShellLiveBlock(state, success) {
675739
675947
  }
675740
675948
  state.status = success ? "ok" : "failed";
675741
675949
  }
675950
+ function shellLiveBlockFingerprint(state) {
675951
+ const sec = Math.floor(Math.max(0, Date.now() - state.startedAt) / 1e3);
675952
+ return `${state.status}|${state.lines.length}|${state.currentLine.length}|${sec}`;
675953
+ }
675742
675954
  function buildShellLiveBlockLines(state, width) {
675743
675955
  const w = Math.max(36, width);
675744
675956
  const inner = Math.max(1, w - 4);
@@ -677779,6 +677991,10 @@ var init_direct_input = __esm({
677779
677991
  this._deleteWordLeft();
677780
677992
  return;
677781
677993
  case 21:
677994
+ if (this.line.length === 0) {
677995
+ this.emit("ctrl-u");
677996
+ return;
677997
+ }
677782
677998
  this.line = this.line.slice(this.cursor);
677783
677999
  this.cursor = 0;
677784
678000
  return;
@@ -681497,20 +681713,20 @@ async function handleNexusStatus(ctx3) {
681497
681713
  join163(process.cwd(), ".omnius", "nexus-peer-state.json"),
681498
681714
  join163(homedir56(), ".omnius", "nexus-peer-cache.json")
681499
681715
  ];
681500
- const states = [];
681716
+ const states2 = [];
681501
681717
  for (const p2 of statePaths) {
681502
681718
  if (!existsSync151(p2)) continue;
681503
681719
  try {
681504
681720
  const raw = readFileSync123(p2, "utf-8");
681505
- states.push({ source: p2, data: JSON.parse(raw) });
681721
+ states2.push({ source: p2, data: JSON.parse(raw) });
681506
681722
  } catch (e2) {
681507
- states.push({ source: p2, error: String(e2) });
681723
+ states2.push({ source: p2, error: String(e2) });
681508
681724
  }
681509
681725
  }
681510
681726
  const config = loadConfig();
681511
681727
  sendJson2(res, 200, {
681512
- connected: states.length > 0,
681513
- peer_cache_files: states,
681728
+ connected: states2.length > 0,
681729
+ peer_cache_files: states2,
681514
681730
  agent_name: loadAgentName(),
681515
681731
  backend_url: config.backendUrl
681516
681732
  });
@@ -684700,6 +684916,100 @@ body { display:flex; flex-direction:column; height:100vh; margin:0; overflow:hid
684700
684916
  border-color: var(--color-border-strong);
684701
684917
  }
684702
684918
 
684919
+ .settings-provider-module-grid {
684920
+ display: grid;
684921
+ grid-template-columns: repeat(auto-fit, minmax(156px, 1fr));
684922
+ gap: 10px;
684923
+ }
684924
+ .settings-provider-module {
684925
+ min-height: 118px;
684926
+ border: 1px solid var(--color-border);
684927
+ border-radius: 8px;
684928
+ background: var(--color-bg-input);
684929
+ color: var(--color-fg);
684930
+ display: grid;
684931
+ align-content: center;
684932
+ justify-items: center;
684933
+ gap: 7px;
684934
+ padding: 12px;
684935
+ text-align: center;
684936
+ font: inherit;
684937
+ cursor: pointer;
684938
+ }
684939
+ .settings-provider-module:hover {
684940
+ background: var(--color-bg-hover);
684941
+ border-color: var(--color-border-strong);
684942
+ }
684943
+ .settings-provider-module.active {
684944
+ border-color: var(--color-brand);
684945
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-brand) 45%, transparent);
684946
+ }
684947
+ .settings-provider-brand {
684948
+ width: 34px;
684949
+ height: 34px;
684950
+ border-radius: 8px;
684951
+ border: 1px solid var(--color-border);
684952
+ background: var(--color-bg);
684953
+ display: inline-grid;
684954
+ place-items: center;
684955
+ overflow: hidden;
684956
+ color: var(--color-brand);
684957
+ font-weight: 700;
684958
+ }
684959
+ .settings-provider-brand img {
684960
+ width: 22px;
684961
+ height: 22px;
684962
+ object-fit: contain;
684963
+ }
684964
+ .settings-provider-module strong {
684965
+ font-size: 0.78rem;
684966
+ font-weight: 700;
684967
+ max-width: 100%;
684968
+ overflow-wrap: anywhere;
684969
+ }
684970
+ .settings-provider-module small {
684971
+ color: var(--color-fg-muted);
684972
+ font-size: 0.68rem;
684973
+ line-height: 1.25;
684974
+ }
684975
+ .settings-provider-setup {
684976
+ border: 1px solid var(--color-border);
684977
+ border-radius: 8px;
684978
+ background: var(--color-bg-elevated);
684979
+ padding: 12px;
684980
+ display: grid;
684981
+ gap: 10px;
684982
+ }
684983
+ .settings-provider-setup-head {
684984
+ display: grid;
684985
+ grid-template-columns: auto minmax(0, 1fr);
684986
+ gap: 10px;
684987
+ align-items: center;
684988
+ }
684989
+ .settings-provider-setup-head strong {
684990
+ display: block;
684991
+ font-size: 0.82rem;
684992
+ }
684993
+ .settings-provider-setup-head small,
684994
+ .settings-provider-meta {
684995
+ color: var(--color-fg-muted);
684996
+ font-size: 0.7rem;
684997
+ }
684998
+ .settings-provider-actions {
684999
+ display: flex;
685000
+ gap: 8px;
685001
+ align-items: center;
685002
+ flex-wrap: wrap;
685003
+ }
685004
+ .settings-provider-link {
685005
+ color: var(--color-brand);
685006
+ border: 1px solid var(--color-border);
685007
+ border-radius: var(--radius-sm);
685008
+ padding: 4px 8px;
685009
+ text-decoration: none;
685010
+ font-size: 0.7rem;
685011
+ }
685012
+
684703
685013
  /* Settings models list rows */
684704
685014
  #settings-models-list .row,
684705
685015
  #mm-list .row {
@@ -685399,8 +685709,8 @@ body { display:flex; flex-direction:column; height:100vh; margin:0; overflow:hid
685399
685709
  </label>
685400
685710
  </section>
685401
685711
  <section class="settings-pane" id="settings-pane-connections" role="tabpanel" hidden>
685402
- <h4>Backend</h4>
685403
- <p style="font-size:0.74rem;color:var(--color-fg-muted);margin:6px 0 12px">Loaded from /v1/config edits POST /v1/config/endpoint.</p>
685712
+ <h4>Inference providers</h4>
685713
+ <p style="font-size:0.74rem;color:var(--color-fg-muted);margin:6px 0 12px">Choose a provider module, add auth when needed, then save it to the daemon endpoint.</p>
685404
685714
  <div id="settings-connections-host">
685405
685715
  <button onclick="loadSettingsConnections()" style="font-size:0.74rem">load current</button>
685406
685716
  </div>
@@ -692234,32 +692544,21 @@ async function loadSettingsConnections() {
692234
692544
  '</div>';
692235
692545
  // Stash history globally so click handlers can resolve index → record.
692236
692546
  window.__omniusEndpointHistory = history;
692547
+ const activeProviderId = settingsProviderIdForUrl(ep);
692548
+ const selectedProviderId = settingsProviderById(window.__omniusSelectedProviderModule)
692549
+ ? window.__omniusSelectedProviderModule
692550
+ : (activeProviderId || 'ollama');
692551
+ window.__omniusSelectedProviderModule = selectedProviderId;
692237
692552
  host.innerHTML =
692238
692553
  '<div style="display:flex;flex-direction:column;gap:14px">' +
692239
- // Quick presets — one-click apply for the common defaults so the
692240
- // user doesn't have to type or even pick a backend type. Selecting
692241
- // a preset fills the URL + backend type fields below; clicking
692242
- // "Apply preset" saves directly without further input.
692243
692554
  '<div>' +
692244
- '<label style="display:block;font-size:0.78rem;font-weight:500;margin-bottom:6px">Quick preset</label>' +
692245
- '<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">' +
692246
- '<select id="settings-conn-preset" style="flex:1;min-width:240px;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:6px 10px;border-radius:var(--radius-sm);font-size:0.78rem">' +
692247
- '<option value="">— select preset —</option>' +
692248
- '<option value="ollama">Ollama (http://127.0.0.1:11434)</option>' +
692249
- '<option value="ollama-lan">Ollama on LAN (http://0.0.0.0:11434)</option>' +
692250
- '<option value="vllm">vLLM (http://127.0.0.1:8000/v1)</option>' +
692251
- '<option value="lmstudio">LM Studio (http://127.0.0.1:1234/v1)</option>' +
692252
- '<option value="openai">OpenAI (https://api.openai.com/v1)</option>' +
692253
- '<option value="anthropic">Anthropic (https://api.anthropic.com/v1)</option>' +
692254
- '<option value="chutes">Chutes (https://llm.chutes.ai/v1)</option>' +
692255
- '<option value="groq">Groq (https://api.groq.com/openai/v1)</option>' +
692256
- '<option value="deepinfra">DeepInfra (https://api.deepinfra.com/v1/openai)</option>' +
692257
- '</select>' +
692258
- '<button class="omnius-btn-secondary" type="button" onclick="applyEndpointPreset(true)" style="background:var(--color-accent);color:var(--color-accent-fg);border-color:var(--color-accent)">apply preset</button>' +
692259
- '<button class="omnius-btn-secondary" type="button" onclick="applyEndpointPreset(false)" title="fill the fields below without saving">load to form</button>' +
692555
+ '<div style="display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px">' +
692556
+ '<label style="display:block;font-size:0.78rem;font-weight:500">Provider modules</label>' +
692557
+ '<span style="font-size:0.68rem;color:var(--color-fg-muted)">' + escapeHtml(settingsProviderGroupSummary()) + '</span>' +
692260
692558
  '</div>' +
692261
- '<p style="font-size:0.7rem;color:var(--color-fg-muted);margin:4px 0 0">Pick a preset and click <b>apply preset</b> to switch backends instantly. <b>load to form</b> just populates the fields below for further editing.</p>' +
692559
+ renderSettingsProviderModules(selectedProviderId, ep) +
692262
692560
  '</div>' +
692561
+ '<div id="settings-provider-setup" class="settings-provider-setup">' + renderSettingsProviderSetup(selectedProviderId) + '</div>' +
692263
692562
  '<div>' +
692264
692563
  '<label style="display:block;font-size:0.78rem;font-weight:500;margin-bottom:6px">Endpoint history</label>' +
692265
692564
  histHTML +
@@ -692300,17 +692599,142 @@ async function loadSettingsConnections() {
692300
692599
  // Map preset key → { url, backendType, requiresAuth, label }. Used by
692301
692600
  // applyEndpointPreset() below to populate the URL + type fields with one
692302
692601
  // click, optionally saving immediately.
692303
- const _OMNIUS_ENDPOINT_PRESETS = {
692304
- 'ollama': { url: 'http://127.0.0.1:11434', backendType: 'ollama' },
692305
- 'ollama-lan': { url: 'http://0.0.0.0:11434', backendType: 'ollama' },
692306
- 'vllm': { url: 'http://127.0.0.1:8000/v1', backendType: 'vllm' },
692307
- 'lmstudio': { url: 'http://127.0.0.1:1234/v1', backendType: 'vllm' },
692308
- 'openai': { url: 'https://api.openai.com/v1', backendType: 'vllm', requiresAuth: true },
692309
- 'anthropic': { url: 'https://api.anthropic.com/v1', backendType: 'vllm', requiresAuth: true },
692310
- 'chutes': { url: 'https://llm.chutes.ai/v1', backendType: 'vllm', requiresAuth: true },
692311
- 'groq': { url: 'https://api.groq.com/openai/v1', backendType: 'vllm', requiresAuth: true },
692312
- 'deepinfra': { url: 'https://api.deepinfra.com/v1/openai', backendType: 'vllm', requiresAuth: true },
692313
- };
692602
+ const _OMNIUS_ENDPOINT_PROVIDERS = [
692603
+ { id: 'ollama', label: 'Ollama', group: 'Local models', domain: 'ollama.com', url: 'http://127.0.0.1:11434', backendType: 'ollama', local: true, description: 'Local Ollama runtime on port 11434.', docsUrl: 'https://docs.ollama.com/api' },
692604
+ { id: 'lmstudio', label: 'LM Studio', group: 'Local models', domain: 'lmstudio.ai', url: 'http://127.0.0.1:1234/v1', backendType: 'vllm', local: true, description: 'Local OpenAI-compatible server on port 1234.', docsUrl: 'https://lmstudio.ai/docs' },
692605
+ { id: 'vllm', label: 'vLLM', group: 'Local models', domain: 'docs.vllm.ai', url: 'http://127.0.0.1:8000/v1', backendType: 'vllm', local: true, description: 'Self-hosted OpenAI-compatible vLLM endpoint.', docsUrl: 'https://docs.vllm.ai' },
692606
+ { id: 'openai', label: 'OpenAI', group: 'Cloud providers', domain: 'openai.com', url: 'https://api.openai.com/v1', backendType: 'vllm', requiresAuth: true, description: 'OpenAI API-compatible models.', apiKeyUrl: 'https://platform.openai.com/api-keys', docsUrl: 'https://platform.openai.com/docs/api-reference/authentication' },
692607
+ { id: 'anthropic', label: 'Anthropic', group: 'Cloud providers', domain: 'anthropic.com', url: 'https://api.anthropic.com/v1', backendType: 'vllm', requiresAuth: true, description: 'Claude via Anthropic API.', apiKeyUrl: 'https://console.anthropic.com/settings/keys', docsUrl: 'https://docs.anthropic.com/en/api/overview' },
692608
+ { id: 'openrouter', label: 'OpenRouter', group: 'Cloud providers', domain: 'openrouter.ai', url: 'https://openrouter.ai/api/v1', backendType: 'vllm', requiresAuth: true, description: 'OpenAI-compatible routing across many hosted models.', apiKeyUrl: 'https://openrouter.ai/keys', docsUrl: 'https://openrouter.ai/docs' },
692609
+ { id: 'chutes', label: 'Chutes', group: 'Cloud providers', domain: 'chutes.ai', url: 'https://llm.chutes.ai/v1', backendType: 'vllm', requiresAuth: true, description: 'Chutes OpenAI-compatible model endpoint.', apiKeyUrl: 'https://chutes.ai/app/api', docsUrl: 'https://docs.chutes.ai' },
692610
+ { id: 'groq', label: 'Groq', group: 'Cloud providers', domain: 'groq.com', url: 'https://api.groq.com/openai/v1', backendType: 'vllm', requiresAuth: true, description: 'Groq OpenAI-compatible inference.', apiKeyUrl: 'https://console.groq.com/keys', docsUrl: 'https://console.groq.com/docs' },
692611
+ { id: 'deepinfra', label: 'DeepInfra', group: 'Cloud providers', domain: 'deepinfra.com', url: 'https://api.deepinfra.com/v1/openai', backendType: 'vllm', requiresAuth: true, description: 'DeepInfra OpenAI-compatible hosted models.', apiKeyUrl: 'https://deepinfra.com/dash/api_keys', docsUrl: 'https://deepinfra.com/docs/openai_api' },
692612
+ { id: 'together', label: 'Together AI', group: 'Cloud providers', domain: 'together.ai', url: 'https://api.together.xyz/v1', backendType: 'vllm', requiresAuth: true, description: 'Together OpenAI-compatible inference.', apiKeyUrl: 'https://api.together.xyz/settings/api-keys', docsUrl: 'https://docs.together.ai/docs/openai-api-compatibility' },
692613
+ { id: 'fireworks', label: 'Fireworks', group: 'Cloud providers', domain: 'fireworks.ai', url: 'https://api.fireworks.ai/inference/v1', backendType: 'vllm', requiresAuth: true, description: 'Fireworks OpenAI-compatible inference.', apiKeyUrl: 'https://fireworks.ai/account/api-keys', docsUrl: 'https://docs.fireworks.ai' },
692614
+ { id: 'mistral', label: 'Mistral', group: 'Cloud providers', domain: 'mistral.ai', url: 'https://api.mistral.ai/v1', backendType: 'vllm', requiresAuth: true, description: 'Mistral hosted model endpoint.', apiKeyUrl: 'https://console.mistral.ai/api-keys', docsUrl: 'https://docs.mistral.ai' },
692615
+ { id: 'cerebras', label: 'Cerebras', group: 'Cloud providers', domain: 'cerebras.ai', url: 'https://api.cerebras.ai/v1', backendType: 'vllm', requiresAuth: true, description: 'Cerebras OpenAI-compatible inference.', apiKeyUrl: 'https://cloud.cerebras.ai/platform', docsUrl: 'https://inference-docs.cerebras.ai' },
692616
+ { id: 'sambanova', label: 'SambaNova', group: 'Cloud providers', domain: 'sambanova.ai', url: 'https://api.sambanova.ai/v1', backendType: 'vllm', requiresAuth: true, description: 'SambaNova OpenAI-compatible inference.', apiKeyUrl: 'https://cloud.sambanova.ai/apis', docsUrl: 'https://docs.sambanova.ai' },
692617
+ { id: 'nvidia', label: 'NVIDIA NIM', group: 'Cloud providers', domain: 'nvidia.com', url: 'https://integrate.api.nvidia.com/v1', backendType: 'vllm', requiresAuth: true, description: 'NVIDIA-hosted NIM models.', apiKeyUrl: 'https://build.nvidia.com', docsUrl: 'https://docs.api.nvidia.com/nim' },
692618
+ { id: 'hyperbolic', label: 'Hyperbolic', group: 'Cloud providers', domain: 'hyperbolic.xyz', url: 'https://api.hyperbolic.xyz/v1', backendType: 'vllm', requiresAuth: true, description: 'Hyperbolic OpenAI-compatible inference.', apiKeyUrl: 'https://app.hyperbolic.xyz/settings', docsUrl: 'https://docs.hyperbolic.xyz' },
692619
+ { id: 'custom', label: 'Custom', group: 'Custom endpoint', domain: '', url: '', backendType: 'vllm', requiresAuth: false, description: 'Any OpenAI-compatible endpoint.' },
692620
+ ];
692621
+ const _OMNIUS_ENDPOINT_PRESETS = Object.fromEntries(_OMNIUS_ENDPOINT_PROVIDERS.map(p => [p.id, p]));
692622
+
692623
+ function settingsProviderById(id) {
692624
+ return _OMNIUS_ENDPOINT_PROVIDERS.find(p => p.id === id) || null;
692625
+ }
692626
+
692627
+ function settingsProviderIdForUrl(url) {
692628
+ const u = String(url || '').toLowerCase();
692629
+ if (!u) return '';
692630
+ if (u.includes('11434') || u.includes('ollama')) return 'ollama';
692631
+ if (u.includes('1234') || u.includes('lmstudio')) return 'lmstudio';
692632
+ if (u.includes('8000') || u.includes('vllm')) return 'vllm';
692633
+ if (u.includes('api.openai.com')) return 'openai';
692634
+ if (u.includes('api.anthropic.com')) return 'anthropic';
692635
+ if (u.includes('openrouter.ai')) return 'openrouter';
692636
+ if (u.includes('chutes.ai')) return 'chutes';
692637
+ if (u.includes('api.groq.com')) return 'groq';
692638
+ if (u.includes('api.deepinfra.com')) return 'deepinfra';
692639
+ if (u.includes('api.together.xyz')) return 'together';
692640
+ if (u.includes('api.fireworks.ai')) return 'fireworks';
692641
+ if (u.includes('api.mistral.ai')) return 'mistral';
692642
+ if (u.includes('api.cerebras.ai')) return 'cerebras';
692643
+ if (u.includes('api.sambanova.ai')) return 'sambanova';
692644
+ if (u.includes('integrate.api.nvidia.com')) return 'nvidia';
692645
+ if (u.includes('api.hyperbolic.xyz')) return 'hyperbolic';
692646
+ return 'custom';
692647
+ }
692648
+
692649
+ function settingsProviderGroupSummary() {
692650
+ const groups = [];
692651
+ for (const p of _OMNIUS_ENDPOINT_PROVIDERS) {
692652
+ if (!groups.includes(p.group)) groups.push(p.group);
692653
+ }
692654
+ return groups.join(' / ');
692655
+ }
692656
+
692657
+ function settingsProviderIcon(provider) {
692658
+ const initial = escapeHtml(String(provider.label || '?').trim().charAt(0).toUpperCase() || '?');
692659
+ if (!provider.domain) return '<span class="settings-provider-brand"><span>' + initial + '</span></span>';
692660
+ const src = 'https://www.google.com/s2/favicons?domain=' + encodeURIComponent(provider.domain) + '&sz=64';
692661
+ return '<span class="settings-provider-brand"><img src="' + escapeHtml(src) + '" alt="" onerror="this.hidden=true;this.nextElementSibling.hidden=false"><span hidden>' + initial + '</span></span>';
692662
+ }
692663
+
692664
+ function renderSettingsProviderModules(selectedId, currentUrl) {
692665
+ const activeId = settingsProviderIdForUrl(currentUrl);
692666
+ return '<div class="settings-provider-module-grid">' + _OMNIUS_ENDPOINT_PROVIDERS.map(provider => {
692667
+ const selected = provider.id === selectedId;
692668
+ const active = provider.id === activeId;
692669
+ const cls = 'settings-provider-module' + (selected ? ' active' : '');
692670
+ const safeId = escapeHtml(provider.id);
692671
+ const meta = provider.group + (active ? ' - active' : (provider.requiresAuth ? ' - API key' : ''));
692672
+ return '<button type="button" class="' + cls + '" data-provider-id="' + safeId + '" onclick="selectSettingsProviderModule(\\'' + safeId + '\\', false)">' +
692673
+ settingsProviderIcon(provider) +
692674
+ '<strong>' + escapeHtml(provider.label) + '</strong>' +
692675
+ '<small>' + escapeHtml(meta) + '</small>' +
692676
+ '</button>';
692677
+ }).join('') + '</div>';
692678
+ }
692679
+
692680
+ function renderSettingsProviderSetup(providerId) {
692681
+ const provider = settingsProviderById(providerId) || settingsProviderById('custom');
692682
+ if (!provider) return '';
692683
+ const endpoint = provider.url || 'custom URL';
692684
+ const auth = provider.requiresAuth ? 'API key required' : (provider.local ? 'Local endpoint' : 'Auth optional');
692685
+ const links = [
692686
+ provider.apiKeyUrl ? '<a class="settings-provider-link" href="' + escapeHtml(provider.apiKeyUrl) + '" target="_blank" rel="noopener noreferrer">key</a>' : '',
692687
+ provider.docsUrl ? '<a class="settings-provider-link" href="' + escapeHtml(provider.docsUrl) + '" target="_blank" rel="noopener noreferrer">docs</a>' : '',
692688
+ ].filter(Boolean).join('');
692689
+ return '<div class="settings-provider-setup-head">' +
692690
+ settingsProviderIcon(provider) +
692691
+ '<div><strong>' + escapeHtml(provider.label) + '</strong><small>' + escapeHtml(provider.description || provider.group) + '</small></div>' +
692692
+ '</div>' +
692693
+ '<div class="settings-provider-meta">Endpoint <code>' + escapeHtml(endpoint) + '</code> · ' + escapeHtml(auth) + '</div>' +
692694
+ '<div class="settings-provider-actions">' +
692695
+ '<button class="omnius-btn-secondary" type="button" onclick="selectSettingsProviderModule(\\'' + escapeHtml(provider.id) + '\\', true)" style="background:var(--color-accent);color:var(--color-accent-fg);border-color:var(--color-accent)">use provider</button>' +
692696
+ '<button class="omnius-btn-secondary" type="button" onclick="selectSettingsProviderModule(\\'' + escapeHtml(provider.id) + '\\', false)">load to form</button>' +
692697
+ '<button class="omnius-btn-secondary" type="button" onclick="testSettingsConnections()">test</button>' +
692698
+ links +
692699
+ '</div>';
692700
+ }
692701
+
692702
+ function updateSettingsProviderSetup(providerId) {
692703
+ const host = document.getElementById('settings-provider-setup');
692704
+ if (host) host.innerHTML = renderSettingsProviderSetup(providerId);
692705
+ document.querySelectorAll('.settings-provider-module').forEach(btn => {
692706
+ btn.classList.toggle('active', btn.getAttribute('data-provider-id') === providerId);
692707
+ });
692708
+ }
692709
+
692710
+ async function selectSettingsProviderModule(providerId, apply) {
692711
+ const provider = settingsProviderById(providerId);
692712
+ if (!provider) return;
692713
+ window.__omniusSelectedProviderModule = provider.id;
692714
+ updateSettingsProviderSetup(provider.id);
692715
+ const inp = document.getElementById('settings-conn-endpoint');
692716
+ const bt = document.getElementById('settings-conn-backend-type');
692717
+ const auth = document.getElementById('settings-conn-auth');
692718
+ const status = document.getElementById('settings-conn-status');
692719
+ if (inp && provider.url) inp.value = provider.url;
692720
+ if (bt && provider.backendType) bt.value = provider.backendType;
692721
+ if (status) {
692722
+ status.textContent = provider.url ? (provider.label + ' loaded') : 'enter a custom endpoint URL below';
692723
+ status.style.color = 'var(--color-fg-muted)';
692724
+ }
692725
+ if (!apply) return;
692726
+ if (!provider.url && inp && !String(inp.value || '').trim()) {
692727
+ if (status) { status.textContent = 'enter a custom endpoint URL first'; status.style.color = 'var(--color-warning)'; }
692728
+ return;
692729
+ }
692730
+ if (provider.requiresAuth && (!auth || !auth.value) && !window.__omniusAuthAlreadySet) {
692731
+ if (status) { status.textContent = provider.label + ' requires an auth key'; status.style.color = 'var(--color-warning)'; }
692732
+ return;
692733
+ }
692734
+ await saveSettingsConnections();
692735
+ }
692736
+ window.selectSettingsProviderModule = selectSettingsProviderModule;
692737
+ window.updateSettingsProviderSetup = updateSettingsProviderSetup;
692314
692738
 
692315
692739
  // One-click endpoint switcher. apply=true saves directly (no typing
692316
692740
  // needed). apply=false just fills the URL/backend-type fields so the
@@ -692431,7 +692855,7 @@ function autoDetectBackendType(url) {
692431
692855
  let detected = 'unknown';
692432
692856
  if (u.includes('11434') || u.includes('ollama')) detected = 'ollama';
692433
692857
  else if (u.startsWith('peer://')) detected = 'nexus';
692434
- else if (u.includes('vllm') || u.includes('openai.com') || u.includes('api.anthropic.com') || u.includes('chutes') || u.includes('groq') || u.includes('deepinfra') || u.includes('/v1')) detected = 'vllm';
692858
+ else if (u.includes('vllm') || u.includes('lmstudio') || u.includes('openai.com') || u.includes('api.anthropic.com') || u.includes('openrouter') || u.includes('chutes') || u.includes('groq') || u.includes('deepinfra') || u.includes('together') || u.includes('fireworks') || u.includes('mistral') || u.includes('cerebras') || u.includes('sambanova') || u.includes('nvidia') || u.includes('hyperbolic') || u.includes('/v1')) detected = 'vllm';
692435
692859
  if (sel.value === '' || sel.value === 'unknown') sel.value = detected;
692436
692860
  }
692437
692861
 
@@ -707598,15 +708022,21 @@ ${entry.fullContent}`
707598
708022
  );
707599
708023
  };
707600
708024
  let liveShellBlock = null;
708025
+ const liveShellFingerprint = () => liveShellBlock ? shellLiveBlockFingerprint(liveShellBlock.state) : "";
708026
+ let lastLiveShellPaint = "";
707601
708027
  const scheduleLiveShellRepaint = () => {
707602
708028
  if (!liveShellBlock || liveShellBlock.repaintTimer || !statusBar?.isActive)
707603
708029
  return;
707604
708030
  liveShellBlock.repaintTimer = setTimeout(() => {
707605
708031
  if (!liveShellBlock) return;
707606
708032
  liveShellBlock.repaintTimer = null;
707607
- if (statusBar?.isActive) statusBar.refreshDisplay();
708033
+ const fp = liveShellFingerprint();
708034
+ if (fp !== lastLiveShellPaint) {
708035
+ lastLiveShellPaint = fp;
708036
+ if (statusBar?.isActive) statusBar.refreshDynamicBlocks();
708037
+ }
707608
708038
  if (liveShellBlock.state.status === "running") scheduleLiveShellRepaint();
707609
- }, 33);
708039
+ }, 120);
707610
708040
  liveShellBlock.repaintTimer.unref?.();
707611
708041
  };
707612
708042
  let gpuRecoveryBlock = null;
@@ -707764,6 +708194,7 @@ ${entry.fullContent}`
707764
708194
  const state = createShellLiveBlockState(command);
707765
708195
  const id = `shell-live-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
707766
708196
  liveShellBlock = { id, state, repaintTimer: null };
708197
+ lastLiveShellPaint = "";
707767
708198
  liveShellStatusBar.registerDynamicBlock(
707768
708199
  id,
707769
708200
  (width) => buildShellLiveBlockLines(state, width)
@@ -714318,6 +714749,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
714318
714749
  process.stderr.write(c3.red("Clipboard paste failed\n"));
714319
714750
  }
714320
714751
  });
714752
+ rl.on("ctrl-u", () => {
714753
+ try {
714754
+ toggleAll();
714755
+ statusBar?.refreshDynamicBlocks();
714756
+ } catch {
714757
+ }
714758
+ });
714321
714759
  rl.on("close", () => {
714322
714760
  if (interactiveExiting) return;
714323
714761
  interactiveExiting = true;
@@ -714910,6 +715348,7 @@ var init_interactive = __esm({
714910
715348
  init_platforms();
714911
715349
  init_status_bar();
714912
715350
  init_shell_live_block();
715351
+ init_tool_collapse_store();
714913
715352
  init_daemon_registry();
714914
715353
  init_dist9();
714915
715354
  init_overlay_lock();
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.324",
3
+ "version": "1.0.325",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.324",
9
+ "version": "1.0.325",
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.324",
3
+ "version": "1.0.325",
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",