open-agents-ai 0.187.395 → 0.187.397

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
@@ -528877,6 +528877,15 @@ import { totalmem as totalmem2 } from "node:os";
528877
528877
  function isImageGenModel(name10, family) {
528878
528878
  return IMAGE_GEN_PATTERNS.some((p2) => p2.test(name10) || family && p2.test(family));
528879
528879
  }
528880
+ function parseShowNumCtx(show) {
528881
+ const sources = [show.parameters, show.modelfile];
528882
+ for (const source of sources) {
528883
+ if (!source) continue;
528884
+ const match = source.match(/\b(?:PARAMETER\s+)?num_ctx\s+(\d+)/i);
528885
+ if (match) return parseInt(match[1], 10);
528886
+ }
528887
+ return null;
528888
+ }
528880
528889
  async function fetchOllamaModels(baseUrl) {
528881
528890
  const url = `${normalizeBaseUrl(baseUrl)}/api/tags`;
528882
528891
  const resp = await fetch(url, {
@@ -528916,12 +528925,10 @@ async function fetchOllamaModels(baseUrl) {
528916
528925
  const sr = showResults[i2];
528917
528926
  if (sr?.status !== "fulfilled" || !sr.value) continue;
528918
528927
  const show = sr.value;
528919
- if (show.parameters) {
528920
- const match = show.parameters.match(/num_ctx\s+(\d+)/);
528921
- if (match) {
528922
- result[i2].contextLength = parseInt(match[1], 10);
528923
- continue;
528924
- }
528928
+ const explicitNumCtx = parseShowNumCtx(show);
528929
+ if (explicitNumCtx) {
528930
+ result[i2].contextLength = explicitNumCtx;
528931
+ continue;
528925
528932
  }
528926
528933
  if (show.model_info) {
528927
528934
  const info = show.model_info;
@@ -529223,10 +529230,8 @@ async function queryModelContextSize(baseUrl, modelName) {
529223
529230
  });
529224
529231
  if (!res.ok) return null;
529225
529232
  const data = await res.json();
529226
- if (data.parameters) {
529227
- const match = data.parameters.match(/num_ctx\s+(\d+)/);
529228
- if (match) return parseInt(match[1], 10);
529229
- }
529233
+ const explicitNumCtx = parseShowNumCtx(data);
529234
+ if (explicitNumCtx) return explicitNumCtx;
529230
529235
  if (data.model_info) {
529231
529236
  const info = data.model_info;
529232
529237
  const arch2 = info["general.architecture"];
@@ -532391,7 +532396,9 @@ var init_status_bar = __esm({
532391
532396
  }
532392
532397
  refreshHeaderPanels() {
532393
532398
  this._rebuildHeaderPanels();
532394
- if (this.active) this.refreshHeaderContent();
532399
+ if (!this.active) return;
532400
+ if (this._bannerRefresh) this._bannerRefresh();
532401
+ else this.refreshHeaderContent();
532395
532402
  }
532396
532403
  refreshHeaderAndFooter() {
532397
532404
  this.refreshHeaderPanels();
@@ -532435,14 +532442,34 @@ var init_status_bar = __esm({
532435
532442
  }
532436
532443
  return "remote";
532437
532444
  }
532438
- buildHeaderVersionText() {
532439
- const parts = [` OA v${this._version}`];
532445
+ buildHeaderIdentitySegments() {
532446
+ const parts = [` OA v${this._version} `];
532440
532447
  const model = this.summarizeHeaderModelName();
532441
532448
  const transport = this.summarizeHeaderTransport();
532442
- if (model) parts.push(model);
532443
- if (transport) parts.push(transport);
532444
- if (this._updateLatest) parts[parts.length - 1] += " ↑";
532445
- return parts.join(" | ");
532449
+ if (model) parts.push(` ${model} `);
532450
+ if (transport) parts.push(` ${transport} `);
532451
+ if (this._updateLatest) {
532452
+ if (parts.length === 0) parts.push(" ");
532453
+ else parts[parts.length - 1] += "↑ ";
532454
+ }
532455
+ return parts;
532456
+ }
532457
+ buildHeaderIdentityRender() {
532458
+ const segments = this.buildHeaderIdentitySegments();
532459
+ let text = "";
532460
+ let width = 0;
532461
+ const separatorOffsets = [];
532462
+ for (let i2 = 0; i2 < segments.length; i2++) {
532463
+ const segment = segments[i2];
532464
+ if (i2 > 0) {
532465
+ separatorOffsets.push(width);
532466
+ text += `${BOX_FG}${BOX_V}${RESET2}${PANEL_BG_SEQ}`;
532467
+ width += 1;
532468
+ }
532469
+ text += `\x1B[1;38;5;${TEXT_PRIMARY}m${PANEL_BG_SEQ}${segment}`;
532470
+ width += segment.length;
532471
+ }
532472
+ return { text, width, separatorOffsets };
532446
532473
  }
532447
532474
  setBackendInfo(backendType, backendUrl) {
532448
532475
  this._headerBackendType = backendType;
@@ -532484,24 +532511,36 @@ var init_status_bar = __esm({
532484
532511
  this._headerPanels = [];
532485
532512
  const savedIdx = this._headerPanelIndex;
532486
532513
  const availW = Math.max(10, termCols() - 5);
532487
- const renderBtn = (cmd, label) => {
532514
+ const linkify = (cmd, label) => {
532488
532515
  const cmdPrefix = cmd.startsWith("view:") ? "oa-view:" + cmd.slice(5) : "oa-cmd:" + cmd;
532516
+ return `\x1B]8;;${cmdPrefix}\x07${label}\x1B]8;;\x07`;
532517
+ };
532518
+ const buttonFg = (cmd) => {
532489
532519
  let fg3 = TEXT_DIM;
532490
532520
  if (cmd === "voice" && this._voiceActive) fg3 = 82;
532491
532521
  if (cmd === "nexus") {
532492
532522
  fg3 = this._nexusStatus === "connected" ? 82 : this._nexusStatus === "connecting" ? 208 : 196;
532493
532523
  }
532494
- return `\x1B]8;;${cmdPrefix}\x07\x1B[38;5;${fg3}m${label}\x1B]8;;\x07`;
532524
+ return fg3;
532495
532525
  };
532496
- const verText = this.buildHeaderVersionText();
532526
+ const decorateMenuButton = (cmd, label) => {
532527
+ const fg3 = buttonFg(cmd);
532528
+ const body = `⡇ ${label} ⢸`;
532529
+ return linkify(cmd, `\x1B[4m\x1B[53m\x1B[38;5;${fg3}m${body}\x1B[24m\x1B[55m`);
532530
+ };
532531
+ const renderBtn = (cmd, label) => {
532532
+ const fg3 = buttonFg(cmd);
532533
+ return linkify(cmd, `\x1B[38;5;${fg3}m${label}`);
532534
+ };
532535
+ const identity3 = this.buildHeaderIdentityRender();
532497
532536
  const menuBtns = [
532498
- { cmd: "help", label: " help ", w: 6 },
532499
- { cmd: "voice", label: " voice ", w: 7 },
532500
- { cmd: "model", label: " model ", w: 7 },
532501
- { cmd: "endpoint", label: " endpoint ", w: 10 },
532502
- { cmd: "sponsor", label: " sponsor ", w: 9 }
532537
+ { cmd: "help", label: "help", w: "⡇ help ⢸".length },
532538
+ { cmd: "voice", label: "voice", w: "⡇ voice ⢸".length },
532539
+ { cmd: "model", label: "model", w: "⡇ model ⢸".length },
532540
+ { cmd: "endpoint", label: "endpoint", w: "⡇ endpoint ⢸".length },
532541
+ { cmd: "sponsor", label: "sponsor", w: "⡇ sponsor ⢸".length }
532503
532542
  ];
532504
- const verW = verText.length;
532543
+ const verW = identity3.width;
532505
532544
  let menuPages = [];
532506
532545
  let curPage = [];
532507
532546
  let curW = verW + 1;
@@ -532523,7 +532562,7 @@ var init_status_bar = __esm({
532523
532562
  let out = "";
532524
532563
  let usedW = 0;
532525
532564
  if (isFirstPage) {
532526
- out += `\x1B[1;38;5;${TEXT_PRIMARY}m${verText}\x1B[0m`;
532565
+ out += identity3.text;
532527
532566
  usedW += verW;
532528
532567
  }
532529
532568
  let btnTotalW = 0;
@@ -532531,7 +532570,7 @@ var init_status_bar = __esm({
532531
532570
  const gap = Math.max(1, innerW - usedW - btnTotalW);
532532
532571
  out += `\x1B[38;5;${TEXT_DIM}m${" ".repeat(gap)}`;
532533
532572
  for (const btn of btns) {
532534
- out += renderBtn(btn.cmd, btn.label) + " ";
532573
+ out += decorateMenuButton(btn.cmd, btn.label) + " ";
532535
532574
  }
532536
532575
  return out;
532537
532576
  }, {
@@ -532595,18 +532634,27 @@ var init_status_bar = __esm({
532595
532634
  nextHeaderPanel() {
532596
532635
  if (this._headerPanels.length <= 1) return;
532597
532636
  this._headerPanelIndex = (this._headerPanelIndex + 1) % this._headerPanels.length;
532598
- this.refreshHeaderContent();
532637
+ if (this._bannerRefresh) this._bannerRefresh();
532638
+ else this.refreshHeaderContent();
532599
532639
  }
532600
532640
  /** Switch to the previous header panel (wraps around) */
532601
532641
  prevHeaderPanel() {
532602
532642
  if (this._headerPanels.length <= 1) return;
532603
532643
  this._headerPanelIndex = (this._headerPanelIndex - 1 + this._headerPanels.length) % this._headerPanels.length;
532604
- this.refreshHeaderContent();
532644
+ if (this._bannerRefresh) this._bannerRefresh();
532645
+ else this.refreshHeaderContent();
532605
532646
  }
532606
532647
  /** Get current panel id */
532607
532648
  get currentHeaderPanel() {
532608
532649
  return this._headerPanels[this._headerPanelIndex]?.id ?? "main";
532609
532650
  }
532651
+ getHeaderBorderSeparatorColumns(termWidth = termCols()) {
532652
+ const panel = this._headerPanels[this._headerPanelIndex];
532653
+ if (!panel?.meta?.isFirstPage || panel.meta.kind !== "main") return [];
532654
+ const chrome = this.getHeaderChromeLayout(termWidth);
532655
+ const identity3 = this.buildHeaderIdentityRender();
532656
+ return identity3.separatorOffsets.map((offset) => chrome.contentStartCol + offset).filter((col) => col > 1 && col < termWidth);
532657
+ }
532610
532658
  getHeaderChromeLayout(termWidth) {
532611
532659
  const hasMultiple = this._headerPanels.length > 1;
532612
532660
  const showPrev = hasMultiple && this._headerPanelIndex > 0;
@@ -538676,15 +538724,35 @@ async function isCloudflaredReady() {
538676
538724
  return false;
538677
538725
  }
538678
538726
  function expandedModelName(baseModel) {
538727
+ const canonicalBase = baseModel.replace(/:latest$/i, "");
538728
+ return `open-agents-${canonicalBase.replace(":", "-").replace(/\./g, "")}`;
538729
+ }
538730
+ function legacyExpandedModelName(baseModel) {
538679
538731
  return `open-agents-${baseModel.replace(":", "-").replace(/\./g, "")}`;
538680
538732
  }
538733
+ function expandedModelCandidates(baseModel) {
538734
+ const canonical = expandedModelName(baseModel);
538735
+ const legacy = legacyExpandedModelName(baseModel);
538736
+ return canonical === legacy ? [canonical] : [canonical, legacy];
538737
+ }
538738
+ function parseShowNumCtx2(show) {
538739
+ const sources = [show.parameters, show.modelfile];
538740
+ for (const source of sources) {
538741
+ if (!source) continue;
538742
+ const match = source.match(/\b(?:PARAMETER\s+)?num_ctx\s+(\d+)/i);
538743
+ if (match) return parseInt(match[1], 10);
538744
+ }
538745
+ return 0;
538746
+ }
538681
538747
  async function checkExpandedVariant(modelName, backendUrl) {
538682
538748
  if (modelName.startsWith("open-agents-")) return null;
538683
- const target = expandedModelName(modelName);
538684
538749
  try {
538685
538750
  const models = await fetchOllamaModels(backendUrl);
538686
- const found = models.find((m2) => m2.name === target || m2.name.startsWith(target + ":"));
538687
- return found ? found.name : false;
538751
+ for (const candidate of expandedModelCandidates(modelName)) {
538752
+ const found = models.find((m2) => m2.name === candidate || m2.name.startsWith(candidate + ":"));
538753
+ if (found) return found.name;
538754
+ }
538755
+ return false;
538688
538756
  } catch {
538689
538757
  return false;
538690
538758
  }
@@ -538734,8 +538802,7 @@ async function readExpandedVariantState(backendUrl, modelName) {
538734
538802
  });
538735
538803
  if (!showRes.ok) return null;
538736
538804
  const showData = await showRes.json();
538737
- const numCtxMatch = showData.parameters?.match(/num_ctx\s+(\d+)/);
538738
- const currentNumCtx = numCtxMatch ? parseInt(numCtxMatch[1], 10) : 0;
538805
+ const currentNumCtx = parseShowNumCtx2(showData);
538739
538806
  const fromMatch = showData.modelfile?.match(/^FROM\s+(.+)$/m);
538740
538807
  const baseModel = fromMatch?.[1]?.trim() ?? null;
538741
538808
  return { currentNumCtx, baseModel };
@@ -538743,81 +538810,117 @@ async function readExpandedVariantState(backendUrl, modelName) {
538743
538810
  return null;
538744
538811
  }
538745
538812
  }
538746
- async function repairExpandedVariantIfStale(variantModel, fallbackBaseModel, backendUrl, specs, sizeGB, targetNumCtx, kvBytesPerToken, archMax) {
538747
- const state = await readExpandedVariantState(backendUrl, variantModel);
538748
- if (!state) return { repaired: false, currentNumCtx: 0, baseModel: null };
538749
- if (state.currentNumCtx > 0 && state.currentNumCtx >= targetNumCtx) {
538750
- return { repaired: false, currentNumCtx: state.currentNumCtx, baseModel: state.baseModel };
538751
- }
538752
- const baseModel = state.baseModel && !state.baseModel.startsWith("open-agents-") ? state.baseModel : fallbackBaseModel;
538753
- if (!baseModel) return { repaired: false, currentNumCtx: state.currentNumCtx, baseModel: null };
538754
- const created = await createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerToken, archMax);
538755
- return { repaired: !!created, currentNumCtx: state.currentNumCtx, baseModel };
538813
+ function stripVariantTag(modelName) {
538814
+ return modelName.replace(/:latest$/i, "");
538756
538815
  }
538757
- function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538758
- const customName = expandedModelName(baseModel);
538816
+ function createExpandedVariantContent(baseModel, numCtx) {
538817
+ const numPredict = Math.min(16384, Math.max(2048, Math.floor(numCtx * 0.25)));
538818
+ return [
538819
+ `FROM ${baseModel}`,
538820
+ `PARAMETER num_ctx ${numCtx}`,
538821
+ `PARAMETER temperature 0`,
538822
+ `PARAMETER num_predict ${numPredict}`,
538823
+ `PARAMETER stop "<|endoftext|>"`
538824
+ ].join("\n");
538825
+ }
538826
+ function createExpandedVariantNamed(targetModel, baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538759
538827
  const ctx3 = calculateExpandedVariantContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
538828
+ const modelfileContent = createExpandedVariantContent(baseModel, ctx3.numCtx);
538760
538829
  try {
538761
- const numPredict = Math.min(16384, Math.max(2048, Math.floor(ctx3.numCtx * 0.25)));
538762
- const modelfileContent = [
538763
- `FROM ${baseModel}`,
538764
- `PARAMETER num_ctx ${ctx3.numCtx}`,
538765
- `PARAMETER temperature 0`,
538766
- `PARAMETER num_predict ${numPredict}`,
538767
- `PARAMETER stop "<|endoftext|>"`
538768
- ].join("\n");
538769
538830
  const modelDir2 = join78(homedir28(), ".open-agents", "models");
538770
538831
  mkdirSync34(modelDir2, { recursive: true });
538771
- const modelfilePath = join78(modelDir2, `Modelfile.${customName}`);
538832
+ const modelfilePath = join78(modelDir2, `Modelfile.${targetModel}`);
538772
538833
  writeFileSync31(modelfilePath, modelfileContent + "\n", "utf8");
538773
- execSync47(`ollama create ${customName} -f ${modelfilePath}`, {
538834
+ execSync47(`ollama create ${targetModel} -f ${modelfilePath}`, {
538774
538835
  stdio: "pipe",
538775
538836
  timeout: 12e4
538776
538837
  });
538777
- return customName;
538838
+ return targetModel;
538778
538839
  } catch {
538779
538840
  return null;
538780
538841
  }
538781
538842
  }
538782
- async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538783
- const customName = expandedModelName(baseModel);
538843
+ async function createExpandedVariantNamedAsync(targetModel, baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538784
538844
  const ctx3 = calculateExpandedVariantContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
538845
+ const modelfileContent = createExpandedVariantContent(baseModel, ctx3.numCtx);
538785
538846
  try {
538786
- const numPredict = Math.min(16384, Math.max(2048, Math.floor(ctx3.numCtx * 0.25)));
538787
- const modelfileContent = [
538788
- `FROM ${baseModel}`,
538789
- `PARAMETER num_ctx ${ctx3.numCtx}`,
538790
- `PARAMETER temperature 0`,
538791
- `PARAMETER num_predict ${numPredict}`,
538792
- `PARAMETER stop "<|endoftext|>"`
538793
- ].join("\n");
538794
538847
  const modelDir2 = join78(homedir28(), ".open-agents", "models");
538795
538848
  mkdirSync34(modelDir2, { recursive: true });
538796
- const modelfilePath = join78(modelDir2, `Modelfile.${customName}`);
538849
+ const modelfilePath = join78(modelDir2, `Modelfile.${targetModel}`);
538797
538850
  writeFileSync31(modelfilePath, modelfileContent + "\n", "utf8");
538798
- await execAsync2(`ollama create ${customName} -f ${modelfilePath}`, {
538851
+ await execAsync2(`ollama create ${targetModel} -f ${modelfilePath}`, {
538799
538852
  timeout: 12e4
538800
538853
  });
538801
- return customName;
538854
+ return targetModel;
538802
538855
  } catch {
538803
538856
  return null;
538804
538857
  }
538805
538858
  }
538859
+ async function repairExpandedVariantIfStale(variantModel, fallbackBaseModel, backendUrl, specs, sizeGB, targetNumCtx, kvBytesPerToken, archMax) {
538860
+ const state = await readExpandedVariantState(backendUrl, variantModel);
538861
+ const variantName = stripVariantTag(variantModel);
538862
+ if (!state) return { repaired: false, currentNumCtx: 0, baseModel: null, resolvedModel: variantName };
538863
+ const baseModel = state.baseModel && !state.baseModel.startsWith("open-agents-") ? state.baseModel : fallbackBaseModel;
538864
+ if (!baseModel) {
538865
+ return { repaired: false, currentNumCtx: state.currentNumCtx, baseModel: null, resolvedModel: variantName };
538866
+ }
538867
+ const canonicalModel = expandedModelName(baseModel);
538868
+ const needsCtxRepair = !(state.currentNumCtx > 0 && state.currentNumCtx >= targetNumCtx);
538869
+ const needsCanonicalVariant = variantName !== canonicalModel;
538870
+ let repaired = false;
538871
+ if (needsCtxRepair) {
538872
+ const repairedCurrent = await createExpandedVariantNamedAsync(variantName, baseModel, specs, sizeGB, kvBytesPerToken, archMax);
538873
+ repaired = repaired || !!repairedCurrent;
538874
+ }
538875
+ let resolvedModel = variantName;
538876
+ if (needsCanonicalVariant) {
538877
+ const canonicalCreated = await createExpandedVariantNamedAsync(canonicalModel, baseModel, specs, sizeGB, kvBytesPerToken, archMax);
538878
+ if (canonicalCreated) {
538879
+ repaired = true;
538880
+ resolvedModel = canonicalCreated;
538881
+ }
538882
+ } else {
538883
+ resolvedModel = canonicalModel;
538884
+ }
538885
+ return { repaired, currentNumCtx: state.currentNumCtx, baseModel, resolvedModel };
538886
+ }
538887
+ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538888
+ return createExpandedVariantNamed(
538889
+ expandedModelName(baseModel),
538890
+ baseModel,
538891
+ specs,
538892
+ sizeGB,
538893
+ kvBytesPerToken,
538894
+ archMax
538895
+ );
538896
+ }
538897
+ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538898
+ return createExpandedVariantNamedAsync(
538899
+ expandedModelName(baseModel),
538900
+ baseModel,
538901
+ specs,
538902
+ sizeGB,
538903
+ kvBytesPerToken,
538904
+ archMax
538905
+ );
538906
+ }
538806
538907
  async function ensureExpandedContext(modelName, backendUrl) {
538807
538908
  if (modelName.includes("cloud") || modelName.includes(":cloud")) {
538808
538909
  return { model: modelName, created: false, contextLabel: "remote", numCtx: 0 };
538809
538910
  }
538810
538911
  const specs = await detectSystemSpecsAsync();
538811
- const kvInfo = await queryModelKVInfo(backendUrl, modelName);
538912
+ const variantState = modelName.startsWith("open-agents-") ? await readExpandedVariantState(backendUrl, modelName).catch(() => null) : null;
538913
+ const targetModelName = variantState?.baseModel && !variantState.baseModel.startsWith("open-agents-") ? variantState.baseModel : modelName;
538914
+ const kvInfo = await queryModelKVInfo(backendUrl, targetModelName);
538812
538915
  let sizeGB = 4;
538813
538916
  try {
538814
538917
  const models = await fetchOllamaModels(backendUrl);
538815
- sizeGB = modelSizeGB(models, modelName);
538918
+ sizeGB = modelSizeGB(models, targetModelName);
538816
538919
  } catch {
538817
538920
  }
538818
538921
  const ctx3 = calculateExpandedVariantContextWindow(specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
538819
538922
  if (modelName.startsWith("open-agents-")) {
538820
- await repairExpandedVariantIfStale(
538923
+ const repair = await repairExpandedVariantIfStale(
538821
538924
  modelName,
538822
538925
  null,
538823
538926
  backendUrl,
@@ -538826,16 +538929,15 @@ async function ensureExpandedContext(modelName, backendUrl) {
538826
538929
  ctx3.numCtx,
538827
538930
  kvInfo?.kvBytesPerToken,
538828
538931
  kvInfo?.archMax
538829
- ).catch(() => {
538830
- });
538831
- return { model: modelName, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538932
+ ).catch(() => ({ repaired: false, currentNumCtx: 0, baseModel: null, resolvedModel: modelName }));
538933
+ return { model: repair.resolvedModel, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538832
538934
  }
538833
538935
  const existing = await checkExpandedVariant(modelName, backendUrl);
538834
538936
  if (existing === null) {
538835
538937
  return { model: modelName, created: false, contextLabel: "", numCtx: 0 };
538836
538938
  }
538837
538939
  if (typeof existing === "string") {
538838
- await repairExpandedVariantIfStale(
538940
+ const repair = await repairExpandedVariantIfStale(
538839
538941
  existing,
538840
538942
  modelName,
538841
538943
  backendUrl,
@@ -538844,9 +538946,8 @@ async function ensureExpandedContext(modelName, backendUrl) {
538844
538946
  ctx3.numCtx,
538845
538947
  kvInfo?.kvBytesPerToken,
538846
538948
  kvInfo?.archMax
538847
- ).catch(() => {
538848
- });
538849
- return { model: existing, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538949
+ ).catch(() => ({ repaired: false, currentNumCtx: 0, baseModel: null, resolvedModel: existing }));
538950
+ return { model: repair.resolvedModel, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538850
538951
  }
538851
538952
  const created = await createExpandedVariantAsync(modelName, specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
538852
538953
  if (created) {
@@ -538892,7 +538993,7 @@ async function repairAllExpandedVariants(backendUrl) {
538892
538993
  );
538893
538994
  if (result.repaired) {
538894
538995
  summary.repaired.push({
538895
- model: variant.name,
538996
+ model: result.resolvedModel,
538896
538997
  baseModel,
538897
538998
  previousNumCtx: result.currentNumCtx,
538898
538999
  targetNumCtx: target.numCtx
@@ -551090,14 +551191,17 @@ async function handleUpdate(subcommand, ctx3) {
551090
551191
  const sCol = centerCol - Math.floor(statusTrunc.length / 2);
551091
551192
  buf += `\x1B[${boxTop + 3};${sCol}H\x1B[38;5;${getDimColor()}m${statusTrunc}\x1B[0m`;
551092
551193
  buf += `\x1B[0m\x1B8\x1B[?25h\x1B[?2026l`;
551093
- process.stdout.write(buf);
551194
+ overlayWrite(buf);
551094
551195
  }
551095
551196
  function startInstallOverlay(version4) {
551197
+ enterOverlay();
551096
551198
  lockFooterRedraws();
551097
551199
  let frame = 0;
551098
551200
  let status = "";
551201
+ let dismissed = false;
551099
551202
  renderInstallFrame(version4, frame, status);
551100
551203
  const timer = setInterval(() => {
551204
+ if (dismissed) return;
551101
551205
  frame++;
551102
551206
  renderInstallFrame(version4, frame, status);
551103
551207
  }, 80);
@@ -551113,18 +551217,20 @@ async function handleUpdate(subcommand, ctx3) {
551113
551217
  _installTotal = total;
551114
551218
  },
551115
551219
  stop(finalText) {
551220
+ if (dismissed) return;
551116
551221
  clearInterval(timer);
551117
- unlockFooterRedraws();
551118
551222
  status = "__DONE__";
551119
551223
  _installProgress = _installTotal;
551120
551224
  renderInstallFrame(version4, frame, status);
551121
551225
  setTimeout(() => {
551226
+ if (dismissed) return;
551122
551227
  status = finalText;
551123
551228
  renderInstallFrame(version4, frame + 1, finalText);
551124
551229
  }, 300);
551125
551230
  },
551126
551231
  dismiss() {
551127
- unlockFooterRedraws();
551232
+ if (dismissed) return;
551233
+ dismissed = true;
551128
551234
  clearInterval(timer);
551129
551235
  const LD = layout();
551130
551236
  const { tuiBgSeq: getDismissBg } = (init_theme(), __toCommonJS(theme_exports));
@@ -551133,7 +551239,9 @@ async function handleUpdate(subcommand, ctx3) {
551133
551239
  buf += `\x1B[${r2};1H${getDismissBg()}\x1B[2K`;
551134
551240
  }
551135
551241
  buf += "\x1B8";
551136
- process.stdout.write(buf);
551242
+ overlayWrite(buf);
551243
+ unlockFooterRedraws();
551244
+ leaveOverlay();
551137
551245
  }
551138
551246
  };
551139
551247
  }
@@ -551352,6 +551460,8 @@ async function handleUpdate(subcommand, ctx3) {
551352
551460
  });
551353
551461
  if (needsSudo) {
551354
551462
  installOverlay.stop("Requesting permissions...");
551463
+ await new Promise((r2) => setTimeout(r2, 300));
551464
+ installOverlay.dismiss();
551355
551465
  renderInfo2("Global npm directory requires elevated permissions.");
551356
551466
  renderInfo2("Enter your password if prompted...");
551357
551467
  safeWrite("\n");
@@ -558272,6 +558382,8 @@ var init_banner = __esm({
558272
558382
  _pulseFrame = 0;
558273
558383
  /** Whether header zone is focused (Ctrl+Tab highlight) */
558274
558384
  _focused = false;
558385
+ /** Absolute terminal columns where the default header box should branch. */
558386
+ _defaultBoxSeparatorProvider = null;
558275
558387
  constructor() {
558276
558388
  this.width = termCols();
558277
558389
  }
@@ -558287,6 +558399,10 @@ var init_banner = __esm({
558287
558399
  setFocused(focused) {
558288
558400
  this._focused = focused;
558289
558401
  }
558402
+ /** Provide dynamic separator columns for the default header box frame. */
558403
+ setDefaultBoxSeparatorProvider(provider) {
558404
+ this._defaultBoxSeparatorProvider = provider;
558405
+ }
558290
558406
  /** Whether an update badge is showing */
558291
558407
  get hasUpdate() {
558292
558408
  return this._updateAvailable !== null;
@@ -558368,6 +558484,7 @@ var init_banner = __esm({
558368
558484
  const frame = this.currentDesign.frames[this.currentFrame];
558369
558485
  if (!frame) return;
558370
558486
  this.width = termCols();
558487
+ const defaultBoxSeparators = this.currentDesign.type === "default" ? new Set((this._defaultBoxSeparatorProvider?.() ?? []).filter((col) => col > 1 && col < this.width)) : null;
558371
558488
  let buf = "\x1B[?2026h";
558372
558489
  const L = layout();
558373
558490
  for (let r2 = 0; r2 < this.rows; r2++) {
@@ -558377,6 +558494,11 @@ var init_banner = __esm({
558377
558494
  let prevFg = -1, prevBg = -1, prevBold = false;
558378
558495
  for (let c8 = 0; c8 < Math.min(this.width, row.length); c8++) {
558379
558496
  const cell = row[c8];
558497
+ let char = cell.char;
558498
+ if (defaultBoxSeparators?.has(c8 + 1)) {
558499
+ if (r2 === 0) char = "┬";
558500
+ if (r2 === 2) char = "┴";
558501
+ }
558380
558502
  let seq = "";
558381
558503
  if (cell.fg !== prevFg || cell.bg !== prevBg || cell.bold !== prevBold) {
558382
558504
  seq += "\x1B[0m";
@@ -558387,7 +558509,7 @@ var init_banner = __esm({
558387
558509
  prevBg = cell.bg;
558388
558510
  prevBold = cell.bold;
558389
558511
  }
558390
- buf += seq + cell.char;
558512
+ buf += seq + char;
558391
558513
  }
558392
558514
  buf += "\x1B[0m";
558393
558515
  }
@@ -581647,7 +581769,9 @@ async function startInteractive(config, repoPath) {
581647
581769
  const scrollTop = carouselLines > 0 ? carouselLines : 1;
581648
581770
  statusBar.activate(scrollTop);
581649
581771
  setTerminalTitle(void 0, version4);
581772
+ banner.setDefaultBoxSeparatorProvider(() => statusBar.getHeaderBorderSeparatorColumns());
581650
581773
  banner.onAfterRender = () => statusBar.refreshHeaderContent();
581774
+ banner.renderCurrentFrame();
581651
581775
  _wireSubAgentCallbacks = (tool) => {
581652
581776
  tool.setCallbacks({
581653
581777
  onViewRegister: (id, label, type) => {
@@ -582588,7 +582712,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582588
582712
  } catch {
582589
582713
  }
582590
582714
  }
582591
- if (currentConfig.backendType === "ollama" && !currentConfig.model.startsWith("open-agents-")) {
582715
+ if (currentConfig.backendType === "ollama") {
582592
582716
  try {
582593
582717
  const expandResult = await ensureExpandedContext(currentConfig.model, currentConfig.backendUrl);
582594
582718
  if (expandResult.created) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.395",
3
+ "version": "0.187.397",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.395",
9
+ "version": "0.187.397",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.395",
3
+ "version": "0.187.397",
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",