open-agents-ai 0.187.396 → 0.187.398

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;
532525
+ };
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}`);
532495
532534
  };
532496
- const verText = this.buildHeaderVersionText();
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;
@@ -532710,8 +532758,8 @@ var init_status_bar = __esm({
532710
532758
  }
532711
532759
  this._sysClickZones = clickZones;
532712
532760
  }
532713
- const leftArrow = chrome.showPrev ? `\x1B]8;;oa-cmd:header-prev\x07\x1B[38;5;${TEXT_DIM}m◀\x1B]8;;\x07` : "";
532714
- const rightArrow = chrome.showNext ? `\x1B]8;;oa-cmd:header-next\x07\x1B[38;5;${TEXT_DIM}m▶\x1B]8;;\x07` : "";
532761
+ const leftArrow = chrome.showPrev ? `\x1B]8;;oa-cmd:header-prev\x07\x1B[38;5;${TEXT_DIM}m🭮\x1B]8;;\x07` : "";
532762
+ const rightArrow = chrome.showNext ? `\x1B]8;;oa-cmd:header-next\x07\x1B[38;5;${TEXT_DIM}m🭬\x1B]8;;\x07` : "";
532715
532763
  const hdrRow = layout().headerContent;
532716
532764
  let buf = "\x1B7";
532717
532765
  buf += `\x1B[${hdrRow};1H${PANEL_BG_SEQ}\x1B[2K`;
@@ -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
@@ -558281,6 +558382,8 @@ var init_banner = __esm({
558281
558382
  _pulseFrame = 0;
558282
558383
  /** Whether header zone is focused (Ctrl+Tab highlight) */
558283
558384
  _focused = false;
558385
+ /** Absolute terminal columns where the default header box should branch. */
558386
+ _defaultBoxSeparatorProvider = null;
558284
558387
  constructor() {
558285
558388
  this.width = termCols();
558286
558389
  }
@@ -558296,6 +558399,10 @@ var init_banner = __esm({
558296
558399
  setFocused(focused) {
558297
558400
  this._focused = focused;
558298
558401
  }
558402
+ /** Provide dynamic separator columns for the default header box frame. */
558403
+ setDefaultBoxSeparatorProvider(provider) {
558404
+ this._defaultBoxSeparatorProvider = provider;
558405
+ }
558299
558406
  /** Whether an update badge is showing */
558300
558407
  get hasUpdate() {
558301
558408
  return this._updateAvailable !== null;
@@ -558377,6 +558484,7 @@ var init_banner = __esm({
558377
558484
  const frame = this.currentDesign.frames[this.currentFrame];
558378
558485
  if (!frame) return;
558379
558486
  this.width = termCols();
558487
+ const defaultBoxSeparators = this.currentDesign.type === "default" ? new Set((this._defaultBoxSeparatorProvider?.() ?? []).filter((col) => col > 1 && col < this.width)) : null;
558380
558488
  let buf = "\x1B[?2026h";
558381
558489
  const L = layout();
558382
558490
  for (let r2 = 0; r2 < this.rows; r2++) {
@@ -558386,6 +558494,11 @@ var init_banner = __esm({
558386
558494
  let prevFg = -1, prevBg = -1, prevBold = false;
558387
558495
  for (let c8 = 0; c8 < Math.min(this.width, row.length); c8++) {
558388
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
+ }
558389
558502
  let seq = "";
558390
558503
  if (cell.fg !== prevFg || cell.bg !== prevBg || cell.bold !== prevBold) {
558391
558504
  seq += "\x1B[0m";
@@ -558396,7 +558509,7 @@ var init_banner = __esm({
558396
558509
  prevBg = cell.bg;
558397
558510
  prevBold = cell.bold;
558398
558511
  }
558399
- buf += seq + cell.char;
558512
+ buf += seq + char;
558400
558513
  }
558401
558514
  buf += "\x1B[0m";
558402
558515
  }
@@ -581656,7 +581769,9 @@ async function startInteractive(config, repoPath) {
581656
581769
  const scrollTop = carouselLines > 0 ? carouselLines : 1;
581657
581770
  statusBar.activate(scrollTop);
581658
581771
  setTerminalTitle(void 0, version4);
581772
+ banner.setDefaultBoxSeparatorProvider(() => statusBar.getHeaderBorderSeparatorColumns());
581659
581773
  banner.onAfterRender = () => statusBar.refreshHeaderContent();
581774
+ banner.renderCurrentFrame();
581660
581775
  _wireSubAgentCallbacks = (tool) => {
581661
581776
  tool.setCallbacks({
581662
581777
  onViewRegister: (id, label, type) => {
@@ -582597,7 +582712,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582597
582712
  } catch {
582598
582713
  }
582599
582714
  }
582600
- if (currentConfig.backendType === "ollama" && !currentConfig.model.startsWith("open-agents-")) {
582715
+ if (currentConfig.backendType === "ollama") {
582601
582716
  try {
582602
582717
  const expandResult = await ensureExpandedContext(currentConfig.model, currentConfig.backendUrl);
582603
582718
  if (expandResult.created) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.396",
3
+ "version": "0.187.398",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.396",
9
+ "version": "0.187.398",
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.396",
3
+ "version": "0.187.398",
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",