open-agents-ai 0.11.0 → 0.11.1

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.
Files changed (2) hide show
  1. package/dist/index.js +119 -73
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1854,15 +1854,26 @@ var init_memory_read = __esm({
1854
1854
  durationMs: performance.now() - start
1855
1855
  };
1856
1856
  }
1857
+ const entry = entries[key];
1858
+ const artifactTag = entry?.artifactId ? ` [artifact: ${entry.artifactId}]` : "";
1857
1859
  return {
1858
1860
  success: true,
1859
- output: JSON.stringify(entries[key], null, 2),
1861
+ output: JSON.stringify(entry, null, 2) + artifactTag,
1860
1862
  durationMs: performance.now() - start
1861
1863
  };
1862
1864
  }
1865
+ const keys = Object.keys(entries);
1866
+ const summary = keys.map((k) => {
1867
+ const e = entries[k];
1868
+ const aid = e?.artifactId ? ` [${e.artifactId}]` : "";
1869
+ return ` ${k}${aid}`;
1870
+ }).join("\n");
1863
1871
  return {
1864
1872
  success: true,
1865
- output: JSON.stringify(entries, null, 2),
1873
+ output: `Topic: ${topic} (${keys.length} entries)
1874
+ ${summary}
1875
+
1876
+ ${JSON.stringify(entries, null, 2)}`,
1866
1877
  durationMs: performance.now() - start
1867
1878
  };
1868
1879
  } catch (error) {
@@ -1881,6 +1892,7 @@ var init_memory_read = __esm({
1881
1892
  // packages/execution/dist/tools/memory-write.js
1882
1893
  import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir2 } from "node:fs/promises";
1883
1894
  import { resolve as resolve7, join as join4 } from "node:path";
1895
+ import { randomBytes } from "node:crypto";
1884
1896
  var MemoryWriteTool;
1885
1897
  var init_memory_write = __esm({
1886
1898
  "packages/execution/dist/tools/memory-write.js"() {
@@ -1927,15 +1939,32 @@ var init_memory_write = __esm({
1927
1939
  entries = JSON.parse(raw);
1928
1940
  } catch {
1929
1941
  }
1942
+ const artifactId = `mem-${randomBytes(6).toString("hex")}`;
1930
1943
  entries[key] = {
1931
1944
  value,
1932
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1945
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1946
+ artifactId
1933
1947
  };
1934
1948
  await writeFile3(topicFile, JSON.stringify(entries, null, 2), "utf-8");
1935
1949
  }
1950
+ const provenanceDir = resolve7(this.workingDir, ".oa", "provenance");
1951
+ try {
1952
+ await mkdir2(provenanceDir, { recursive: true });
1953
+ const provRecord = {
1954
+ type: "memory_write",
1955
+ topic,
1956
+ key,
1957
+ artifactId: `mem-${randomBytes(6).toString("hex")}`,
1958
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1959
+ source: "agent"
1960
+ };
1961
+ const provFile = join4(provenanceDir, `${Date.now()}-memory-write.json`);
1962
+ await writeFile3(provFile, JSON.stringify(provRecord, null, 2), "utf-8");
1963
+ } catch {
1964
+ }
1936
1965
  return {
1937
1966
  success: true,
1938
- output: `Stored memory: ${topic}.${key}`,
1967
+ output: `Stored memory: ${topic}.${key} [artifact: mem-${Date.now().toString(36)}]`,
1939
1968
  durationMs: performance.now() - start
1940
1969
  };
1941
1970
  } catch (error) {
@@ -8632,8 +8661,30 @@ var init_project_context = __esm({
8632
8661
  function fg(code, text) {
8633
8662
  return isTTY3 ? `\x1B[38;5;${code}m${text}\x1B[0m` : text;
8634
8663
  }
8664
+ function displayWidth(str) {
8665
+ let w = 0;
8666
+ for (const ch of str) {
8667
+ const cp = ch.codePointAt(0);
8668
+ if (cp >= 4352 && cp <= 4447 || // Hangul Jamo
8669
+ cp >= 11904 && cp <= 12350 || // CJK Radicals, Kangxi, CJK Symbols
8670
+ cp >= 12352 && cp <= 13247 || // Hiragana, Katakana, CJK Compat
8671
+ cp >= 13312 && cp <= 19903 || // CJK Ext A
8672
+ cp >= 19968 && cp <= 42191 || // CJK Unified, Yi
8673
+ cp >= 44032 && cp <= 55215 || // Hangul Syllables
8674
+ cp >= 63744 && cp <= 64255 || // CJK Compat Ideographs
8675
+ cp >= 65072 && cp <= 65135 || // CJK Compat Forms
8676
+ cp >= 65281 && cp <= 65376 || // Fullwidth Forms
8677
+ cp >= 65504 && cp <= 65510 || // Fullwidth Signs
8678
+ cp >= 131072 && cp <= 195103) {
8679
+ w += 2;
8680
+ } else {
8681
+ w += 1;
8682
+ }
8683
+ }
8684
+ return w;
8685
+ }
8635
8686
  function buildPlainRibbon(phrases, repeatWidth) {
8636
- const separator = " \xB7 ";
8687
+ const separator = " : ";
8637
8688
  let plain = "";
8638
8689
  while (plain.length < repeatWidth * 3) {
8639
8690
  for (const p of phrases) {
@@ -8669,70 +8720,67 @@ var init_carousel = __esm({
8669
8720
  { text: "imagine freely", color: 219 },
8670
8721
  { text: "liberate creativity", color: 111 },
8671
8722
  // Spanish
8672
- { text: "libertad de informaci\xF3n", color: 214 },
8723
+ { text: "libertad de informacion", color: 214 },
8673
8724
  { text: "crear libremente", color: 208 },
8674
- { text: "c\xF3digo abierto", color: 220 },
8675
- { text: "s\xE9 creativo", color: 226 },
8676
- { text: "imaginaci\xF3n sin l\xEDmites", color: 215 },
8725
+ { text: "codigo abierto", color: 220 },
8726
+ { text: "se creativo", color: 226 },
8727
+ { text: "imaginacion sin limites", color: 215 },
8677
8728
  // French
8678
- { text: "cr\xE9er librement", color: 171 },
8679
- { text: "libert\xE9 d'expression", color: 177 },
8729
+ { text: "creer librement", color: 171 },
8730
+ { text: "liberte d'expression", color: 177 },
8680
8731
  { text: "source ouverte", color: 141 },
8681
8732
  { text: "imaginer sans contrainte", color: 183 },
8682
8733
  // German
8683
8734
  { text: "Freiheit der Muster", color: 77 },
8684
8735
  { text: "frei erschaffen", color: 78 },
8685
8736
  { text: "offene Quelle", color: 114 },
8686
- { text: "grenzenlose Kreativit\xE4t", color: 150 },
8737
+ { text: "grenzenlose Kreativitat", color: 150 },
8687
8738
  // Japanese
8688
- { text: "\u81EA\u7531\u306B\u5275\u9020\u3059\u308B", color: 204 },
8689
- { text: "\u958B\u6E90\u306E\u7CBE\u795E", color: 210 },
8690
- { text: "\u5236\u7D04\u306A\u304D\u60F3\u50CF\u529B", color: 203 },
8691
- { text: "\u77E5\u8B58\u3092\u5171\u6709\u3059\u308B", color: 209 },
8739
+ { text: "jiyuu ni souzou suru", color: 204 },
8740
+ { text: "kaigen no seishin", color: 210 },
8741
+ { text: "seiyaku naki souzouryoku", color: 203 },
8742
+ { text: "chishiki wo kyouyuu", color: 209 },
8692
8743
  // Korean
8693
- { text: "\uC790\uC720\uB85C\uC6B4 \uCC3D\uC791", color: 105 },
8694
- { text: "\uC624\uD508\uC18C\uC2A4 \uC815\uC2E0", color: 99 },
8695
- { text: "\uC601\uAC10\uC744 \uB098\uB204\uB2E4", color: 135 },
8696
- // Chinese
8697
- { text: "\u958B\u6E90\u81EA\u7531", color: 167 },
8698
- { text: "\u81EA\u7531\u5275\u4F5C", color: 173 },
8699
- { text: "\u77E5\u8B58\u5171\u4EAB", color: 161 },
8700
- { text: "\u7121\u9650\u60F3\u50CF", color: 131 },
8744
+ { text: "jayuroun changjak", color: 105 },
8745
+ { text: "opeunsoseu jeongsin", color: 99 },
8746
+ { text: "yeonggam eul nanuda", color: 135 },
8701
8747
  // Russian
8702
- { text: "\u0441\u0432\u043E\u0431\u043E\u0434\u0430 \u0442\u0432\u043E\u0440\u0447\u0435\u0441\u0442\u0432\u0430", color: 73 },
8703
- { text: "\u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0439 \u0438\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434", color: 67 },
8704
- { text: "\u0441\u043E\u0437\u0434\u0430\u0432\u0430\u0439 \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u043E", color: 109 },
8748
+ { text: "svoboda tvorchestva", color: 73 },
8749
+ { text: "otkrytyy iskhodnyy kod", color: 67 },
8750
+ { text: "sozdavay svobodno", color: 109 },
8705
8751
  // Portuguese
8706
8752
  { text: "liberdade de criar", color: 179 },
8707
- { text: "c\xF3digo aberto", color: 185 },
8708
- { text: "imagina\xE7\xE3o sem fronteiras", color: 186 },
8753
+ { text: "codigo aberto", color: 185 },
8754
+ { text: "imaginacao sem fronteiras", color: 186 },
8709
8755
  // Italian
8710
8756
  { text: "creare liberamente", color: 144 },
8711
- { text: "libert\xE0 di espressione", color: 180 },
8712
- // Hindi
8713
- { text: "\u0916\u0941\u0932\u0940 \u0938\u094B\u091A", color: 198 },
8714
- { text: "\u092E\u0941\u0915\u094D\u0924 \u0930\u091A\u0928\u093E", color: 199 },
8715
- // Arabic
8716
- { text: "\u062D\u0631\u064A\u0629 \u0627\u0644\u0625\u0628\u062F\u0627\u0639", color: 222 },
8717
- { text: "\u0645\u0635\u062F\u0631 \u0645\u0641\u062A\u0648\u062D", color: 228 },
8757
+ { text: "liberta di espressione", color: 180 },
8718
8758
  // Turkish
8719
- { text: "\xF6zg\xFCrce yarat", color: 156 },
8720
- { text: "a\xE7\u0131k kaynak", color: 192 },
8759
+ { text: "ozgurce yarat", color: 156 },
8760
+ { text: "acik kaynak", color: 192 },
8721
8761
  // Swedish
8722
8762
  { text: "skapa fritt", color: 116 },
8723
- { text: "\xF6ppen k\xE4llkod", color: 122 },
8763
+ { text: "oppen kallkod", color: 122 },
8724
8764
  // Dutch
8725
- { text: "vrij cre\xEBren", color: 152 },
8765
+ { text: "vrij creeren", color: 152 },
8726
8766
  // Polish
8727
- { text: "tw\xF3rz swobodnie", color: 188 },
8767
+ { text: "tworz swobodnie", color: 188 },
8728
8768
  // Greek
8729
- { text: "\u03B4\u03B7\u03BC\u03B9\u03BF\u03CD\u03C1\u03B3\u03B7\u03C3\u03B5 \u03B5\u03BB\u03B5\u03CD\u03B8\u03B5\u03C1\u03B1", color: 75 }
8769
+ { text: "dimiourgia elefthera", color: 75 },
8770
+ // Hindi
8771
+ { text: "khuli soch", color: 198 },
8772
+ { text: "mukt rachna", color: 199 },
8773
+ // Arabic
8774
+ { text: "hurriyat al-ibdaa", color: 222 },
8775
+ { text: "masdar maftuh", color: 228 }
8730
8776
  ];
8731
8777
  Carousel = class {
8732
8778
  rows;
8733
8779
  timer = null;
8734
8780
  width;
8735
8781
  lineCount = 3;
8782
+ /** Total rows reserved at top: 3 carousel + 1 blank separator */
8783
+ reservedRows = 4;
8736
8784
  started = false;
8737
8785
  resizeHandler = null;
8738
8786
  constructor() {
@@ -8742,11 +8790,8 @@ var init_carousel = __esm({
8742
8790
  const indices2 = Array.from({ length: PHRASES.length }, (_, i) => i).sort(() => Math.random() - 0.5);
8743
8791
  this.rows = [
8744
8792
  createRow(indices0, 2, -1),
8745
- // fast left
8746
8793
  createRow(indices1, 1, 1),
8747
- // medium right
8748
8794
  createRow(indices2, 1.5, -1)
8749
- // slow-medium left
8750
8795
  ];
8751
8796
  this.rebuildRibbons();
8752
8797
  }
@@ -8757,13 +8802,8 @@ var init_carousel = __esm({
8757
8802
  }
8758
8803
  /**
8759
8804
  * Start the animation.
8760
- *
8761
- * 1. Writes 3 empty lines to reserve space
8762
- * 2. Sets DECSTBM scroll region to row 4+ (everything below carousel)
8763
- * 3. Moves cursor into the scroll region
8764
- * 4. Starts animation timer that writes ONLY to rows 1-3
8765
- *
8766
- * The cursor never leaves the scroll region, so readline works perfectly.
8805
+ * Reserves rows 1-3 for carousel, row 4 as blank separator.
8806
+ * Sets scroll region to row 5+ for all content/readline.
8767
8807
  */
8768
8808
  start() {
8769
8809
  if (!isTTY3)
@@ -8771,17 +8811,17 @@ var init_carousel = __esm({
8771
8811
  this.started = true;
8772
8812
  const termRows = process.stdout.rows ?? 24;
8773
8813
  process.stdout.write("\x1B[1;1H");
8774
- for (let i = 0; i < this.lineCount; i++) {
8814
+ for (let i = 0; i < this.reservedRows; i++) {
8775
8815
  process.stdout.write("\x1B[2K\n");
8776
8816
  }
8777
- process.stdout.write(`\x1B[${this.lineCount + 1};${termRows}r`);
8778
- process.stdout.write(`\x1B[${this.lineCount + 1};1H`);
8817
+ process.stdout.write(`\x1B[${this.reservedRows + 1};${termRows}r`);
8818
+ process.stdout.write(`\x1B[${this.reservedRows + 1};1H`);
8779
8819
  this.resizeHandler = () => {
8780
8820
  this.width = process.stdout.columns ?? 80;
8781
8821
  const newRows = process.stdout.rows ?? 24;
8782
8822
  this.rebuildRibbons();
8783
8823
  if (this.started) {
8784
- process.stdout.write(`\x1B[${this.lineCount + 1};${newRows}r`);
8824
+ process.stdout.write(`\x1B[${this.reservedRows + 1};${newRows}r`);
8785
8825
  }
8786
8826
  };
8787
8827
  process.stdout.on("resize", this.resizeHandler);
@@ -8795,40 +8835,41 @@ var init_carousel = __esm({
8795
8835
  }
8796
8836
  this.renderFrame();
8797
8837
  }, 66);
8798
- return this.lineCount;
8838
+ return this.reservedRows;
8799
8839
  }
8800
8840
  /**
8801
- * Render one animation frame.
8802
- *
8803
- * Uses save/restore cursor (DECSC/DECRC) to briefly visit rows 1-3,
8804
- * then return. Because the scroll region is set to row 4+, the cursor
8805
- * restore puts it back exactly where readline expects it.
8841
+ * Render one animation frame into rows 1-3 only.
8842
+ * Row 4 is left blank as a separator.
8806
8843
  */
8807
8844
  renderFrame() {
8808
8845
  if (!isTTY3)
8809
8846
  return;
8810
8847
  let buf = "\x1B7";
8848
+ buf += "\x1B[?7l";
8811
8849
  for (let i = 0; i < this.rows.length; i++) {
8812
8850
  const line = this.extractWindow(this.rows[i]);
8813
8851
  buf += `\x1B[${i + 1};1H\x1B[2K${line}`;
8814
8852
  }
8853
+ buf += `\x1B[4;1H\x1B[2K`;
8854
+ buf += "\x1B[?7h";
8815
8855
  buf += "\x1B8";
8816
8856
  process.stdout.write(buf);
8817
8857
  }
8818
8858
  /**
8819
8859
  * Extract a terminal-width colored window from a scrolling ribbon.
8860
+ * Uses column-aware width to prevent CJK/fullwidth character overflow.
8820
8861
  */
8821
8862
  extractWindow(row) {
8822
- const w = this.width;
8863
+ const maxCols = this.width;
8823
8864
  const plain = row.renderedPlain;
8824
8865
  if (!plain)
8825
8866
  return "";
8826
8867
  let start = Math.floor(Math.abs(row.offset)) % plain.length;
8827
8868
  if (start < 0)
8828
8869
  start += plain.length;
8829
- const separator = " \xB7 ";
8870
+ const separator = " : ";
8830
8871
  let coloredLine = "";
8831
- let charCount = 0;
8872
+ let colCount = 0;
8832
8873
  let charInPhrase = 0;
8833
8874
  let skipChars = start;
8834
8875
  const phrases = row.phrases;
@@ -8843,20 +8884,25 @@ var init_carousel = __esm({
8843
8884
  skipChars -= fullText.length;
8844
8885
  fullIdx++;
8845
8886
  }
8846
- while (charCount < w) {
8887
+ while (colCount < maxCols) {
8847
8888
  const p = phrases[fullIdx % phrases.length];
8848
8889
  const fullText = p.text + separator;
8849
8890
  const remaining = fullText.slice(charInPhrase);
8850
8891
  for (const ch of remaining) {
8851
- if (charCount >= w)
8892
+ const chWidth = displayWidth(ch);
8893
+ if (colCount + chWidth > maxCols) {
8894
+ if (colCount < maxCols)
8895
+ coloredLine += " ";
8896
+ colCount = maxCols;
8852
8897
  break;
8898
+ }
8853
8899
  const inPhrase = charInPhrase < p.text.length;
8854
8900
  if (inPhrase) {
8855
8901
  coloredLine += fg(p.color, ch);
8856
8902
  } else {
8857
8903
  coloredLine += `\x1B[2m${ch}\x1B[0m`;
8858
8904
  }
8859
- charCount++;
8905
+ colCount += chWidth;
8860
8906
  charInPhrase++;
8861
8907
  }
8862
8908
  fullIdx++;
@@ -8865,7 +8911,7 @@ var init_carousel = __esm({
8865
8911
  return coloredLine;
8866
8912
  }
8867
8913
  /**
8868
- * Stop the animation, clear the carousel lines, and reset scroll region.
8914
+ * Stop the animation, clear rows 1-4, reset scroll region.
8869
8915
  */
8870
8916
  stop() {
8871
8917
  if (this.timer) {
@@ -8879,7 +8925,7 @@ var init_carousel = __esm({
8879
8925
  if (!isTTY3 || !this.started)
8880
8926
  return;
8881
8927
  let buf = "\x1B7";
8882
- for (let i = 0; i < this.lineCount; i++) {
8928
+ for (let i = 0; i < this.reservedRows; i++) {
8883
8929
  buf += `\x1B[${i + 1};1H\x1B[2K`;
8884
8930
  }
8885
8931
  buf += "\x1B[r";
@@ -8887,7 +8933,6 @@ var init_carousel = __esm({
8887
8933
  process.stdout.write(buf);
8888
8934
  this.started = false;
8889
8935
  }
8890
- /** Check if carousel is running */
8891
8936
  get isRunning() {
8892
8937
  return this.timer !== null;
8893
8938
  }
@@ -9735,8 +9780,9 @@ async function startInteractive(config, repoPath) {
9735
9780
  process.stdout.on("resize", () => {
9736
9781
  if (!carouselRetired) {
9737
9782
  const termRows = process.stdout.rows ?? 24;
9738
- process.stdout.write(`\x1B[${carouselLines + 1};${termRows}r`);
9739
- process.stdout.write(`\x1B[${carouselLines + 1};1H\x1B[J`);
9783
+ const scrollStart = carousel.reservedRows + 1;
9784
+ process.stdout.write(`\x1B[${scrollStart};${termRows}r`);
9785
+ process.stdout.write(`\x1B[${scrollStart};1H\x1B[J`);
9740
9786
  renderRichHeader({
9741
9787
  model: currentConfig.model,
9742
9788
  version,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
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",