open-agents-ai 0.187.394 → 0.187.395

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", {
@@ -581800,9 +581909,7 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
581800
581909
  if (ctxSize) {
581801
581910
  resolvedContextWindowSize = ctxSize;
581802
581911
  statusBar.setContextWindowSize(ctxSize);
581803
- if (activeTask) {
581804
- activeTask.runner.setContextWindowSize(ctxSize);
581805
- }
581912
+ setActiveTaskContextWindowSize(ctxSize);
581806
581913
  }
581807
581914
  }).catch(() => {
581808
581915
  });
@@ -581817,6 +581924,37 @@ ${opts.systemPromptAddition}` : `Working directory: ${repoRoot}`;
581817
581924
  }).catch(() => {
581818
581925
  });
581819
581926
  statusBar.setHeaderIdentity(config.model, config.backendType, config.backendUrl);
581927
+ const formatCtxLabel = (tokens) => tokens >= 1024 ? `${Math.floor(tokens / 1024)}K` : String(tokens);
581928
+ let expandedVariantSweepPromise = null;
581929
+ const startExpandedVariantRepairSweep = (backendType, backendUrl) => {
581930
+ const normalizedUrl = normalizeBaseUrl(backendUrl);
581931
+ const isLocalOllama = backendType === "ollama" && (normalizedUrl.includes("127.0.0.1") || normalizedUrl.includes("localhost") || normalizedUrl.includes("0.0.0.0"));
581932
+ if (!isLocalOllama || expandedVariantSweepPromise) return;
581933
+ expandedVariantSweepPromise = repairAllExpandedVariants(normalizedUrl).then(async (summary) => {
581934
+ if (summary.repaired.length > 0) {
581935
+ const preview = summary.repaired.slice(0, 3).map((entry) => `${entry.model} ${formatCtxLabel(entry.previousNumCtx)}->${formatCtxLabel(entry.targetNumCtx)}`).join(", ");
581936
+ writeContent(() => {
581937
+ renderInfo2(`Repaired ${summary.repaired.length} open-agents model variant${summary.repaired.length === 1 ? "" : "s"} to max context.`);
581938
+ renderInfo2(preview + (summary.repaired.length > 3 ? `, +${summary.repaired.length - 3} more` : ""));
581939
+ });
581940
+ if (currentConfig.backendType === "ollama" && currentConfig.model.startsWith("open-agents-")) {
581941
+ const repairedCtxSize = await queryContextSize(currentConfig.backendUrl, currentConfig.model, currentConfig.apiKey);
581942
+ if (repairedCtxSize) {
581943
+ resolvedContextWindowSize = repairedCtxSize;
581944
+ statusBar.setContextWindowSize(repairedCtxSize);
581945
+ setActiveTaskContextWindowSize(repairedCtxSize);
581946
+ }
581947
+ }
581948
+ } else if (summary.failed.length > 0) {
581949
+ writeContent(() => {
581950
+ renderWarning2(`Expanded-model repair sweep skipped ${summary.failed.length} variant${summary.failed.length === 1 ? "" : "s"} with unreadable metadata.`);
581951
+ });
581952
+ }
581953
+ }).catch(() => {
581954
+ }).finally(() => {
581955
+ expandedVariantSweepPromise = null;
581956
+ });
581957
+ };
581820
581958
  const provider = detectProvider(config.backendUrl);
581821
581959
  const costTracker = new CostTracker(provider.id);
581822
581960
  const sessionMetrics = new SessionMetrics();
@@ -582062,6 +582200,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582062
582200
  }, delayMs);
582063
582201
  }
582064
582202
  let activeTask = null;
582203
+ const setActiveTaskContextWindowSize = (size) => {
582204
+ const runner = activeTask?.runner;
582205
+ if (runner) runner.setContextWindowSize(size);
582206
+ };
582065
582207
  let messageQueue = [];
582066
582208
  let carouselRetired = isResumed;
582067
582209
  let lastSubmittedPrompt = "";
@@ -582463,6 +582605,17 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582463
582605
  } catch {
582464
582606
  }
582465
582607
  }
582608
+ if (currentConfig.backendType === "ollama" && currentConfig.model.startsWith("open-agents-")) {
582609
+ try {
582610
+ const expandedCtxSize = await queryContextSize(currentConfig.backendUrl, currentConfig.model, currentConfig.apiKey);
582611
+ if (expandedCtxSize) {
582612
+ resolvedContextWindowSize = expandedCtxSize;
582613
+ statusBar.setContextWindowSize(expandedCtxSize);
582614
+ setActiveTaskContextWindowSize(expandedCtxSize);
582615
+ }
582616
+ } catch {
582617
+ }
582618
+ }
582466
582619
  if (!isResumed) {
582467
582620
  try {
582468
582621
  const baseUrl = normalizeBaseUrl(currentConfig.backendUrl);
@@ -582733,6 +582886,9 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582733
582886
  });
582734
582887
  setupTasks.push(startupChecksPromise.catch(() => {
582735
582888
  }));
582889
+ startupChecksPromise.finally(() => {
582890
+ startExpandedVariantRepairSweep(currentConfig.backendType, currentConfig.backendUrl);
582891
+ });
582736
582892
  Promise.resolve().then(() => (init_daemon(), daemon_exports)).then(async ({ ensureDaemon: ensureDaemon2, isDaemonRunning: isDaemonRunning2 }) => {
582737
582893
  const apiPort = parseInt(process.env["OA_PORT"] || "11435", 10);
582738
582894
  if (await isDaemonRunning2(apiPort)) {
@@ -582926,6 +583082,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
582926
583082
  } else {
582927
583083
  statusBar.stopRemoteMetricsPolling();
582928
583084
  }
583085
+ startExpandedVariantRepairSweep(backendType, url);
582929
583086
  },
582930
583087
  setKeyPool(keys) {
582931
583088
  if (activeTask) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.394",
3
+ "version": "0.187.395",
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.395",
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.395",
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",