open-agents-ai 0.187.394 → 0.187.396

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
@@ -532397,12 +532397,25 @@ var init_status_bar = __esm({
532397
532397
  this.refreshHeaderPanels();
532398
532398
  if (this.active) this.renderFooterPreserveCursor();
532399
532399
  }
532400
- summarizeHeaderModelName() {
532401
- const raw = this._modelName.trim();
532400
+ normalizeDisplayModelName(rawName) {
532401
+ const raw = rawName.trim();
532402
532402
  if (!raw) return "";
532403
532403
  const leaf = raw.split("/").pop() ?? raw;
532404
- const familySource = leaf.split(":")[0]?.trim() || leaf;
532405
- const paramMatch = raw.match(/(\d+(?:\.\d+)?\s*[bBmMkK])/);
532404
+ const withoutLatest = leaf.replace(/:latest$/i, "");
532405
+ if (!/^open-agents-/i.test(withoutLatest)) return withoutLatest;
532406
+ const derived = withoutLatest.replace(/^open-agents-/i, "");
532407
+ const sizeMatch = derived.match(/-(\d+(?:\.\d+)?[bBmMkK])$/);
532408
+ const size = sizeMatch?.[1]?.toLowerCase() ?? "";
532409
+ let family = sizeMatch ? derived.slice(0, -sizeMatch[0].length) : derived;
532410
+ family = family.replace(/-latest$/i, "");
532411
+ family = family.replace(/^qwen(\d)(\d)(?=$|-)/i, "qwen$1.$2").replace(/^llama(\d)(\d)(?=$|-)/i, "llama$1.$2").replace(/^phi(\d)(\d)(?=$|-)/i, "phi$1.$2").replace(/^deepseekr(\d)(?=$|-)/i, "deepseek-r$1").replace(/^commandr(?=$|-)/i, "command-r").replace(/^commanda(?=$|-)/i, "command-a");
532412
+ return size ? `${family}:${size}` : family;
532413
+ }
532414
+ summarizeHeaderModelName() {
532415
+ const displayName = this.normalizeDisplayModelName(this._modelName);
532416
+ if (!displayName) return "";
532417
+ const familySource = displayName.split(":")[0]?.trim() || displayName;
532418
+ const paramMatch = displayName.match(/(\d+(?:\.\d+)?\s*[bBmMkK])/);
532406
532419
  const param = paramMatch ? paramMatch[1].replace(/\s+/g, "").toLowerCase() : "";
532407
532420
  let summary = param && !familySource.toLowerCase().includes(param) ? `${familySource} ${param}` : familySource;
532408
532421
  if (summary.length > 18) {
@@ -536767,6 +536780,7 @@ __export(setup_exports, {
536767
536780
  pullModelWithAutoUpdate: () => pullModelWithAutoUpdate,
536768
536781
  recommendModel: () => recommendModel,
536769
536782
  renderScoreBar: () => renderScoreBar,
536783
+ repairAllExpandedVariants: () => repairAllExpandedVariants,
536770
536784
  runElevatedCommand: () => runElevatedCommand,
536771
536785
  runSetupWizard: () => runSetupWizard,
536772
536786
  updateOllama: () => updateOllama
@@ -536935,6 +536949,16 @@ function calculateContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax) {
536935
536949
  const label = numCtx >= 1024 ? `${Math.floor(numCtx / 1024)}K` : String(numCtx);
536936
536950
  return { numCtx, label };
536937
536951
  }
536952
+ function formatContextLabel(numCtx) {
536953
+ return numCtx >= 1024 ? `${Math.floor(numCtx / 1024)}K` : String(numCtx);
536954
+ }
536955
+ function calculateExpandedVariantContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax) {
536956
+ if (archMax && archMax > 0) {
536957
+ const numCtx = Math.max(2048, Math.floor(archMax / 1024) * 1024);
536958
+ return { numCtx, label: formatContextLabel(numCtx) };
536959
+ }
536960
+ return calculateContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax);
536961
+ }
536938
536962
  function ask(rl, question) {
536939
536963
  return new Promise((resolve41) => {
536940
536964
  rl.question(question, (answer) => resolve41(answer.trim()));
@@ -538691,16 +538715,48 @@ async function queryModelKVInfo(backendUrl, modelName) {
538691
538715
  const keyDim = info[`${arch2}.attention.key_length`];
538692
538716
  const valDim = info[`${arch2}.attention.value_length`] ?? keyDim;
538693
538717
  const archMax = info[`${arch2}.context_length`];
538694
- if (!nLayers || !nKVHeads || !keyDim || !valDim || !archMax) return null;
538718
+ if (!archMax) return null;
538719
+ if (!nLayers || !nKVHeads || !keyDim || !valDim) return { archMax };
538695
538720
  const kvBytesPerToken = nLayers * nKVHeads * (keyDim + valDim) * 2;
538696
538721
  return { kvBytesPerToken, archMax };
538697
538722
  } catch {
538698
538723
  return null;
538699
538724
  }
538700
538725
  }
538726
+ async function readExpandedVariantState(backendUrl, modelName) {
538727
+ try {
538728
+ const normalized = backendUrl.replace(/\/+$/, "");
538729
+ const showRes = await fetch(`${normalized}/api/show`, {
538730
+ method: "POST",
538731
+ headers: { "Content-Type": "application/json" },
538732
+ body: JSON.stringify({ name: modelName }),
538733
+ signal: AbortSignal.timeout(5e3)
538734
+ });
538735
+ if (!showRes.ok) return null;
538736
+ const showData = await showRes.json();
538737
+ const numCtxMatch = showData.parameters?.match(/num_ctx\s+(\d+)/);
538738
+ const currentNumCtx = numCtxMatch ? parseInt(numCtxMatch[1], 10) : 0;
538739
+ const fromMatch = showData.modelfile?.match(/^FROM\s+(.+)$/m);
538740
+ const baseModel = fromMatch?.[1]?.trim() ?? null;
538741
+ return { currentNumCtx, baseModel };
538742
+ } catch {
538743
+ return null;
538744
+ }
538745
+ }
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 };
538756
+ }
538701
538757
  function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538702
538758
  const customName = expandedModelName(baseModel);
538703
- const ctx3 = calculateContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
538759
+ const ctx3 = calculateExpandedVariantContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
538704
538760
  try {
538705
538761
  const numPredict = Math.min(16384, Math.max(2048, Math.floor(ctx3.numCtx * 0.25)));
538706
538762
  const modelfileContent = [
@@ -538725,7 +538781,7 @@ function createExpandedVariant(baseModel, specs, sizeGB, kvBytesPerToken, archMa
538725
538781
  }
538726
538782
  async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerToken, archMax) {
538727
538783
  const customName = expandedModelName(baseModel);
538728
- const ctx3 = calculateContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
538784
+ const ctx3 = calculateExpandedVariantContextWindow(specs, sizeGB, kvBytesPerToken, archMax);
538729
538785
  try {
538730
538786
  const numPredict = Math.min(16384, Math.max(2048, Math.floor(ctx3.numCtx * 0.25)));
538731
538787
  const modelfileContent = [
@@ -538759,30 +538815,19 @@ async function ensureExpandedContext(modelName, backendUrl) {
538759
538815
  sizeGB = modelSizeGB(models, modelName);
538760
538816
  } catch {
538761
538817
  }
538762
- const ctx3 = calculateContextWindow(specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
538818
+ const ctx3 = calculateExpandedVariantContextWindow(specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
538763
538819
  if (modelName.startsWith("open-agents-")) {
538764
- try {
538765
- const normalized = backendUrl.replace(/\/+$/, "");
538766
- const showRes = await fetch(`${normalized}/api/show`, {
538767
- method: "POST",
538768
- headers: { "Content-Type": "application/json" },
538769
- body: JSON.stringify({ name: modelName }),
538770
- signal: AbortSignal.timeout(5e3)
538771
- });
538772
- if (showRes.ok) {
538773
- const showData = await showRes.json();
538774
- const numCtxMatch = showData.parameters?.match(/num_ctx\s+(\d+)/);
538775
- const currentNumCtx = numCtxMatch ? parseInt(numCtxMatch[1], 10) : 0;
538776
- if (currentNumCtx !== ctx3.numCtx) {
538777
- const fromMatch = showData.modelfile?.match(/^FROM\s+(.+)$/m);
538778
- const baseModel = fromMatch?.[1]?.trim();
538779
- if (baseModel && !baseModel.startsWith("open-agents-")) {
538780
- await createExpandedVariantAsync(baseModel, specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
538781
- }
538782
- }
538783
- }
538784
- } catch {
538785
- }
538820
+ await repairExpandedVariantIfStale(
538821
+ modelName,
538822
+ null,
538823
+ backendUrl,
538824
+ specs,
538825
+ sizeGB,
538826
+ ctx3.numCtx,
538827
+ kvInfo?.kvBytesPerToken,
538828
+ kvInfo?.archMax
538829
+ ).catch(() => {
538830
+ });
538786
538831
  return { model: modelName, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538787
538832
  }
538788
538833
  const existing = await checkExpandedVariant(modelName, backendUrl);
@@ -538790,6 +538835,17 @@ async function ensureExpandedContext(modelName, backendUrl) {
538790
538835
  return { model: modelName, created: false, contextLabel: "", numCtx: 0 };
538791
538836
  }
538792
538837
  if (typeof existing === "string") {
538838
+ await repairExpandedVariantIfStale(
538839
+ existing,
538840
+ modelName,
538841
+ backendUrl,
538842
+ specs,
538843
+ sizeGB,
538844
+ ctx3.numCtx,
538845
+ kvInfo?.kvBytesPerToken,
538846
+ kvInfo?.archMax
538847
+ ).catch(() => {
538848
+ });
538793
538849
  return { model: existing, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538794
538850
  }
538795
538851
  const created = await createExpandedVariantAsync(modelName, specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
@@ -538798,6 +538854,59 @@ async function ensureExpandedContext(modelName, backendUrl) {
538798
538854
  }
538799
538855
  return { model: modelName, created: false, contextLabel: ctx3.label, numCtx: ctx3.numCtx };
538800
538856
  }
538857
+ async function repairAllExpandedVariants(backendUrl) {
538858
+ const specs = await detectSystemSpecsAsync();
538859
+ const models = await fetchOllamaModels(backendUrl);
538860
+ const variants = models.filter((model) => /^open-agents-/i.test(model.name));
538861
+ const summary = {
538862
+ scanned: 0,
538863
+ unchanged: 0,
538864
+ repaired: [],
538865
+ failed: []
538866
+ };
538867
+ for (const variant of variants) {
538868
+ summary.scanned += 1;
538869
+ const state = await readExpandedVariantState(backendUrl, variant.name);
538870
+ if (!state) {
538871
+ summary.failed.push({ model: variant.name, reason: "missing-state" });
538872
+ continue;
538873
+ }
538874
+ const baseModel = state.baseModel && !state.baseModel.startsWith("open-agents-") ? state.baseModel : null;
538875
+ if (!baseModel) {
538876
+ summary.failed.push({ model: variant.name, reason: "missing-base-model" });
538877
+ continue;
538878
+ }
538879
+ const sizeGB = modelSizeGB(models, baseModel || variant.name);
538880
+ const kvInfo = await queryModelKVInfo(backendUrl, baseModel);
538881
+ const target = calculateExpandedVariantContextWindow(specs, sizeGB, kvInfo?.kvBytesPerToken, kvInfo?.archMax);
538882
+ try {
538883
+ const result = await repairExpandedVariantIfStale(
538884
+ variant.name,
538885
+ baseModel,
538886
+ backendUrl,
538887
+ specs,
538888
+ sizeGB,
538889
+ target.numCtx,
538890
+ kvInfo?.kvBytesPerToken,
538891
+ kvInfo?.archMax
538892
+ );
538893
+ if (result.repaired) {
538894
+ summary.repaired.push({
538895
+ model: variant.name,
538896
+ baseModel,
538897
+ previousNumCtx: result.currentNumCtx,
538898
+ targetNumCtx: target.numCtx
538899
+ });
538900
+ } else {
538901
+ summary.unchanged += 1;
538902
+ }
538903
+ } catch (err) {
538904
+ const message2 = err instanceof Error ? err.message : String(err);
538905
+ summary.failed.push({ model: variant.name, reason: message2 || "repair-failed" });
538906
+ }
538907
+ }
538908
+ return summary;
538909
+ }
538801
538910
  async function ensureNeovim() {
538802
538911
  try {
538803
538912
  const nvimPath = execSync47("which nvim 2>/dev/null || where nvim 2>nul", {
@@ -550981,14 +551090,17 @@ async function handleUpdate(subcommand, ctx3) {
550981
551090
  const sCol = centerCol - Math.floor(statusTrunc.length / 2);
550982
551091
  buf += `\x1B[${boxTop + 3};${sCol}H\x1B[38;5;${getDimColor()}m${statusTrunc}\x1B[0m`;
550983
551092
  buf += `\x1B[0m\x1B8\x1B[?25h\x1B[?2026l`;
550984
- process.stdout.write(buf);
551093
+ overlayWrite(buf);
550985
551094
  }
550986
551095
  function startInstallOverlay(version4) {
551096
+ enterOverlay();
550987
551097
  lockFooterRedraws();
550988
551098
  let frame = 0;
550989
551099
  let status = "";
551100
+ let dismissed = false;
550990
551101
  renderInstallFrame(version4, frame, status);
550991
551102
  const timer = setInterval(() => {
551103
+ if (dismissed) return;
550992
551104
  frame++;
550993
551105
  renderInstallFrame(version4, frame, status);
550994
551106
  }, 80);
@@ -551004,18 +551116,20 @@ async function handleUpdate(subcommand, ctx3) {
551004
551116
  _installTotal = total;
551005
551117
  },
551006
551118
  stop(finalText) {
551119
+ if (dismissed) return;
551007
551120
  clearInterval(timer);
551008
- unlockFooterRedraws();
551009
551121
  status = "__DONE__";
551010
551122
  _installProgress = _installTotal;
551011
551123
  renderInstallFrame(version4, frame, status);
551012
551124
  setTimeout(() => {
551125
+ if (dismissed) return;
551013
551126
  status = finalText;
551014
551127
  renderInstallFrame(version4, frame + 1, finalText);
551015
551128
  }, 300);
551016
551129
  },
551017
551130
  dismiss() {
551018
- unlockFooterRedraws();
551131
+ if (dismissed) return;
551132
+ dismissed = true;
551019
551133
  clearInterval(timer);
551020
551134
  const LD = layout();
551021
551135
  const { tuiBgSeq: getDismissBg } = (init_theme(), __toCommonJS(theme_exports));
@@ -551024,7 +551138,9 @@ async function handleUpdate(subcommand, ctx3) {
551024
551138
  buf += `\x1B[${r2};1H${getDismissBg()}\x1B[2K`;
551025
551139
  }
551026
551140
  buf += "\x1B8";
551027
- process.stdout.write(buf);
551141
+ overlayWrite(buf);
551142
+ unlockFooterRedraws();
551143
+ leaveOverlay();
551028
551144
  }
551029
551145
  };
551030
551146
  }
@@ -551243,6 +551359,8 @@ async function handleUpdate(subcommand, ctx3) {
551243
551359
  });
551244
551360
  if (needsSudo) {
551245
551361
  installOverlay.stop("Requesting permissions...");
551362
+ await new Promise((r2) => setTimeout(r2, 300));
551363
+ installOverlay.dismiss();
551246
551364
  renderInfo2("Global npm directory requires elevated permissions.");
551247
551365
  renderInfo2("Enter your password if prompted...");
551248
551366
  safeWrite("\n");
@@ -581800,9 +581918,7 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
581800
581918
  if (ctxSize) {
581801
581919
  resolvedContextWindowSize = ctxSize;
581802
581920
  statusBar.setContextWindowSize(ctxSize);
581803
- if (activeTask) {
581804
- activeTask.runner.setContextWindowSize(ctxSize);
581805
- }
581921
+ setActiveTaskContextWindowSize(ctxSize);
581806
581922
  }
581807
581923
  }).catch(() => {
581808
581924
  });
@@ -581817,6 +581933,37 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
581817
581933
  }).catch(() => {
581818
581934
  });
581819
581935
  statusBar.setHeaderIdentity(config.model, config.backendType, config.backendUrl);
581936
+ const formatCtxLabel = (tokens) => tokens >= 1024 ? `${Math.floor(tokens / 1024)}K` : String(tokens);
581937
+ let expandedVariantSweepPromise = null;
581938
+ const startExpandedVariantRepairSweep = (backendType, backendUrl) => {
581939
+ const normalizedUrl = normalizeBaseUrl(backendUrl);
581940
+ const isLocalOllama = backendType === "ollama" && (normalizedUrl.includes("127.0.0.1") || normalizedUrl.includes("localhost") || normalizedUrl.includes("0.0.0.0"));
581941
+ if (!isLocalOllama || expandedVariantSweepPromise) return;
581942
+ expandedVariantSweepPromise = repairAllExpandedVariants(normalizedUrl).then(async (summary) => {
581943
+ if (summary.repaired.length > 0) {
581944
+ const preview = summary.repaired.slice(0, 3).map((entry) => `${entry.model} ${formatCtxLabel(entry.previousNumCtx)}->${formatCtxLabel(entry.targetNumCtx)}`).join(", ");
581945
+ writeContent(() => {
581946
+ renderInfo2(`Repaired ${summary.repaired.length} open-agents model variant${summary.repaired.length === 1 ? "" : "s"} to max context.`);
581947
+ renderInfo2(preview + (summary.repaired.length > 3 ? `, +${summary.repaired.length - 3} more` : ""));
581948
+ });
581949
+ if (currentConfig.backendType === "ollama" && currentConfig.model.startsWith("open-agents-")) {
581950
+ const repairedCtxSize = await queryContextSize(currentConfig.backendUrl, currentConfig.model, currentConfig.apiKey);
581951
+ if (repairedCtxSize) {
581952
+ resolvedContextWindowSize = repairedCtxSize;
581953
+ statusBar.setContextWindowSize(repairedCtxSize);
581954
+ setActiveTaskContextWindowSize(repairedCtxSize);
581955
+ }
581956
+ }
581957
+ } else if (summary.failed.length > 0) {
581958
+ writeContent(() => {
581959
+ renderWarning2(`Expanded-model repair sweep skipped ${summary.failed.length} variant${summary.failed.length === 1 ? "" : "s"} with unreadable metadata.`);
581960
+ });
581961
+ }
581962
+ }).catch(() => {
581963
+ }).finally(() => {
581964
+ expandedVariantSweepPromise = null;
581965
+ });
581966
+ };
581820
581967
  const provider = detectProvider(config.backendUrl);
581821
581968
  const costTracker = new CostTracker(provider.id);
581822
581969
  const sessionMetrics = new SessionMetrics();
@@ -582062,6 +582209,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582062
582209
  }, delayMs);
582063
582210
  }
582064
582211
  let activeTask = null;
582212
+ const setActiveTaskContextWindowSize = (size) => {
582213
+ const runner = activeTask?.runner;
582214
+ if (runner) runner.setContextWindowSize(size);
582215
+ };
582065
582216
  let messageQueue = [];
582066
582217
  let carouselRetired = isResumed;
582067
582218
  let lastSubmittedPrompt = "";
@@ -582463,6 +582614,17 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582463
582614
  } catch {
582464
582615
  }
582465
582616
  }
582617
+ if (currentConfig.backendType === "ollama" && currentConfig.model.startsWith("open-agents-")) {
582618
+ try {
582619
+ const expandedCtxSize = await queryContextSize(currentConfig.backendUrl, currentConfig.model, currentConfig.apiKey);
582620
+ if (expandedCtxSize) {
582621
+ resolvedContextWindowSize = expandedCtxSize;
582622
+ statusBar.setContextWindowSize(expandedCtxSize);
582623
+ setActiveTaskContextWindowSize(expandedCtxSize);
582624
+ }
582625
+ } catch {
582626
+ }
582627
+ }
582466
582628
  if (!isResumed) {
582467
582629
  try {
582468
582630
  const baseUrl = normalizeBaseUrl(currentConfig.backendUrl);
@@ -582733,6 +582895,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582733
582895
  });
582734
582896
  setupTasks.push(startupChecksPromise.catch(() => {
582735
582897
  }));
582898
+ startupChecksPromise.finally(() => {
582899
+ startExpandedVariantRepairSweep(currentConfig.backendType, currentConfig.backendUrl);
582900
+ });
582736
582901
  Promise.resolve().then(() => (init_daemon(), daemon_exports)).then(async ({ ensureDaemon: ensureDaemon2, isDaemonRunning: isDaemonRunning2 }) => {
582737
582902
  const apiPort = parseInt(process.env["OA_PORT"] || "11435", 10);
582738
582903
  if (await isDaemonRunning2(apiPort)) {
@@ -582926,6 +583091,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582926
583091
  } else {
582927
583092
  statusBar.stopRemoteMetricsPolling();
582928
583093
  }
583094
+ startExpandedVariantRepairSweep(backendType, url);
582929
583095
  },
582930
583096
  setKeyPool(keys) {
582931
583097
  if (activeTask) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.394",
3
+ "version": "0.187.396",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.394",
9
+ "version": "0.187.396",
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.394",
3
+ "version": "0.187.396",
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",