open-agents-ai 0.11.0 → 0.11.2
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 +185 -92
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -302,6 +302,17 @@ function performUpdate() {
|
|
|
302
302
|
return false;
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
|
+
function performSilentUpdate() {
|
|
306
|
+
try {
|
|
307
|
+
execSync(`npm install -g ${PACKAGE_NAME}@latest`, {
|
|
308
|
+
stdio: "pipe",
|
|
309
|
+
timeout: 12e4
|
|
310
|
+
});
|
|
311
|
+
return true;
|
|
312
|
+
} catch {
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
305
316
|
function restartProcess() {
|
|
306
317
|
const args = process.argv.slice(1);
|
|
307
318
|
try {
|
|
@@ -1854,15 +1865,26 @@ var init_memory_read = __esm({
|
|
|
1854
1865
|
durationMs: performance.now() - start
|
|
1855
1866
|
};
|
|
1856
1867
|
}
|
|
1868
|
+
const entry = entries[key];
|
|
1869
|
+
const artifactTag = entry?.artifactId ? ` [artifact: ${entry.artifactId}]` : "";
|
|
1857
1870
|
return {
|
|
1858
1871
|
success: true,
|
|
1859
|
-
output: JSON.stringify(
|
|
1872
|
+
output: JSON.stringify(entry, null, 2) + artifactTag,
|
|
1860
1873
|
durationMs: performance.now() - start
|
|
1861
1874
|
};
|
|
1862
1875
|
}
|
|
1876
|
+
const keys = Object.keys(entries);
|
|
1877
|
+
const summary = keys.map((k) => {
|
|
1878
|
+
const e = entries[k];
|
|
1879
|
+
const aid = e?.artifactId ? ` [${e.artifactId}]` : "";
|
|
1880
|
+
return ` ${k}${aid}`;
|
|
1881
|
+
}).join("\n");
|
|
1863
1882
|
return {
|
|
1864
1883
|
success: true,
|
|
1865
|
-
output:
|
|
1884
|
+
output: `Topic: ${topic} (${keys.length} entries)
|
|
1885
|
+
${summary}
|
|
1886
|
+
|
|
1887
|
+
${JSON.stringify(entries, null, 2)}`,
|
|
1866
1888
|
durationMs: performance.now() - start
|
|
1867
1889
|
};
|
|
1868
1890
|
} catch (error) {
|
|
@@ -1881,6 +1903,7 @@ var init_memory_read = __esm({
|
|
|
1881
1903
|
// packages/execution/dist/tools/memory-write.js
|
|
1882
1904
|
import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir2 } from "node:fs/promises";
|
|
1883
1905
|
import { resolve as resolve7, join as join4 } from "node:path";
|
|
1906
|
+
import { randomBytes } from "node:crypto";
|
|
1884
1907
|
var MemoryWriteTool;
|
|
1885
1908
|
var init_memory_write = __esm({
|
|
1886
1909
|
"packages/execution/dist/tools/memory-write.js"() {
|
|
@@ -1927,15 +1950,32 @@ var init_memory_write = __esm({
|
|
|
1927
1950
|
entries = JSON.parse(raw);
|
|
1928
1951
|
} catch {
|
|
1929
1952
|
}
|
|
1953
|
+
const artifactId = `mem-${randomBytes(6).toString("hex")}`;
|
|
1930
1954
|
entries[key] = {
|
|
1931
1955
|
value,
|
|
1932
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1956
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1957
|
+
artifactId
|
|
1933
1958
|
};
|
|
1934
1959
|
await writeFile3(topicFile, JSON.stringify(entries, null, 2), "utf-8");
|
|
1935
1960
|
}
|
|
1961
|
+
const provenanceDir = resolve7(this.workingDir, ".oa", "provenance");
|
|
1962
|
+
try {
|
|
1963
|
+
await mkdir2(provenanceDir, { recursive: true });
|
|
1964
|
+
const provRecord = {
|
|
1965
|
+
type: "memory_write",
|
|
1966
|
+
topic,
|
|
1967
|
+
key,
|
|
1968
|
+
artifactId: `mem-${randomBytes(6).toString("hex")}`,
|
|
1969
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1970
|
+
source: "agent"
|
|
1971
|
+
};
|
|
1972
|
+
const provFile = join4(provenanceDir, `${Date.now()}-memory-write.json`);
|
|
1973
|
+
await writeFile3(provFile, JSON.stringify(provRecord, null, 2), "utf-8");
|
|
1974
|
+
} catch {
|
|
1975
|
+
}
|
|
1936
1976
|
return {
|
|
1937
1977
|
success: true,
|
|
1938
|
-
output: `Stored memory: ${topic}.${key}`,
|
|
1978
|
+
output: `Stored memory: ${topic}.${key} [artifact: mem-${Date.now().toString(36)}]`,
|
|
1939
1979
|
durationMs: performance.now() - start
|
|
1940
1980
|
};
|
|
1941
1981
|
} catch (error) {
|
|
@@ -8632,8 +8672,30 @@ var init_project_context = __esm({
|
|
|
8632
8672
|
function fg(code, text) {
|
|
8633
8673
|
return isTTY3 ? `\x1B[38;5;${code}m${text}\x1B[0m` : text;
|
|
8634
8674
|
}
|
|
8675
|
+
function displayWidth(str) {
|
|
8676
|
+
let w = 0;
|
|
8677
|
+
for (const ch of str) {
|
|
8678
|
+
const cp = ch.codePointAt(0);
|
|
8679
|
+
if (cp >= 4352 && cp <= 4447 || // Hangul Jamo
|
|
8680
|
+
cp >= 11904 && cp <= 12350 || // CJK Radicals, Kangxi, CJK Symbols
|
|
8681
|
+
cp >= 12352 && cp <= 13247 || // Hiragana, Katakana, CJK Compat
|
|
8682
|
+
cp >= 13312 && cp <= 19903 || // CJK Ext A
|
|
8683
|
+
cp >= 19968 && cp <= 42191 || // CJK Unified, Yi
|
|
8684
|
+
cp >= 44032 && cp <= 55215 || // Hangul Syllables
|
|
8685
|
+
cp >= 63744 && cp <= 64255 || // CJK Compat Ideographs
|
|
8686
|
+
cp >= 65072 && cp <= 65135 || // CJK Compat Forms
|
|
8687
|
+
cp >= 65281 && cp <= 65376 || // Fullwidth Forms
|
|
8688
|
+
cp >= 65504 && cp <= 65510 || // Fullwidth Signs
|
|
8689
|
+
cp >= 131072 && cp <= 195103) {
|
|
8690
|
+
w += 2;
|
|
8691
|
+
} else {
|
|
8692
|
+
w += 1;
|
|
8693
|
+
}
|
|
8694
|
+
}
|
|
8695
|
+
return w;
|
|
8696
|
+
}
|
|
8635
8697
|
function buildPlainRibbon(phrases, repeatWidth) {
|
|
8636
|
-
const separator = "
|
|
8698
|
+
const separator = " : ";
|
|
8637
8699
|
let plain = "";
|
|
8638
8700
|
while (plain.length < repeatWidth * 3) {
|
|
8639
8701
|
for (const p of phrases) {
|
|
@@ -8669,70 +8731,67 @@ var init_carousel = __esm({
|
|
|
8669
8731
|
{ text: "imagine freely", color: 219 },
|
|
8670
8732
|
{ text: "liberate creativity", color: 111 },
|
|
8671
8733
|
// Spanish
|
|
8672
|
-
{ text: "libertad de
|
|
8734
|
+
{ text: "libertad de informacion", color: 214 },
|
|
8673
8735
|
{ text: "crear libremente", color: 208 },
|
|
8674
|
-
{ text: "
|
|
8675
|
-
{ text: "
|
|
8676
|
-
{ text: "
|
|
8736
|
+
{ text: "codigo abierto", color: 220 },
|
|
8737
|
+
{ text: "se creativo", color: 226 },
|
|
8738
|
+
{ text: "imaginacion sin limites", color: 215 },
|
|
8677
8739
|
// French
|
|
8678
|
-
{ text: "
|
|
8679
|
-
{ text: "
|
|
8740
|
+
{ text: "creer librement", color: 171 },
|
|
8741
|
+
{ text: "liberte d'expression", color: 177 },
|
|
8680
8742
|
{ text: "source ouverte", color: 141 },
|
|
8681
8743
|
{ text: "imaginer sans contrainte", color: 183 },
|
|
8682
8744
|
// German
|
|
8683
8745
|
{ text: "Freiheit der Muster", color: 77 },
|
|
8684
8746
|
{ text: "frei erschaffen", color: 78 },
|
|
8685
8747
|
{ text: "offene Quelle", color: 114 },
|
|
8686
|
-
{ text: "grenzenlose
|
|
8748
|
+
{ text: "grenzenlose Kreativitat", color: 150 },
|
|
8687
8749
|
// Japanese
|
|
8688
|
-
{ text: "
|
|
8689
|
-
{ text: "
|
|
8690
|
-
{ text: "
|
|
8691
|
-
{ text: "
|
|
8750
|
+
{ text: "jiyuu ni souzou suru", color: 204 },
|
|
8751
|
+
{ text: "kaigen no seishin", color: 210 },
|
|
8752
|
+
{ text: "seiyaku naki souzouryoku", color: 203 },
|
|
8753
|
+
{ text: "chishiki wo kyouyuu", color: 209 },
|
|
8692
8754
|
// Korean
|
|
8693
|
-
{ text: "
|
|
8694
|
-
{ text: "
|
|
8695
|
-
{ text: "
|
|
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 },
|
|
8755
|
+
{ text: "jayuroun changjak", color: 105 },
|
|
8756
|
+
{ text: "opeunsoseu jeongsin", color: 99 },
|
|
8757
|
+
{ text: "yeonggam eul nanuda", color: 135 },
|
|
8701
8758
|
// Russian
|
|
8702
|
-
{ text: "
|
|
8703
|
-
{ text: "
|
|
8704
|
-
{ text: "
|
|
8759
|
+
{ text: "svoboda tvorchestva", color: 73 },
|
|
8760
|
+
{ text: "otkrytyy iskhodnyy kod", color: 67 },
|
|
8761
|
+
{ text: "sozdavay svobodno", color: 109 },
|
|
8705
8762
|
// Portuguese
|
|
8706
8763
|
{ text: "liberdade de criar", color: 179 },
|
|
8707
|
-
{ text: "
|
|
8708
|
-
{ text: "
|
|
8764
|
+
{ text: "codigo aberto", color: 185 },
|
|
8765
|
+
{ text: "imaginacao sem fronteiras", color: 186 },
|
|
8709
8766
|
// Italian
|
|
8710
8767
|
{ text: "creare liberamente", color: 144 },
|
|
8711
|
-
{ text: "
|
|
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 },
|
|
8768
|
+
{ text: "liberta di espressione", color: 180 },
|
|
8718
8769
|
// Turkish
|
|
8719
|
-
{ text: "
|
|
8720
|
-
{ text: "
|
|
8770
|
+
{ text: "ozgurce yarat", color: 156 },
|
|
8771
|
+
{ text: "acik kaynak", color: 192 },
|
|
8721
8772
|
// Swedish
|
|
8722
8773
|
{ text: "skapa fritt", color: 116 },
|
|
8723
|
-
{ text: "
|
|
8774
|
+
{ text: "oppen kallkod", color: 122 },
|
|
8724
8775
|
// Dutch
|
|
8725
|
-
{ text: "vrij
|
|
8776
|
+
{ text: "vrij creeren", color: 152 },
|
|
8726
8777
|
// Polish
|
|
8727
|
-
{ text: "
|
|
8778
|
+
{ text: "tworz swobodnie", color: 188 },
|
|
8728
8779
|
// Greek
|
|
8729
|
-
{ text: "
|
|
8780
|
+
{ text: "dimiourgia elefthera", color: 75 },
|
|
8781
|
+
// Hindi
|
|
8782
|
+
{ text: "khuli soch", color: 198 },
|
|
8783
|
+
{ text: "mukt rachna", color: 199 },
|
|
8784
|
+
// Arabic
|
|
8785
|
+
{ text: "hurriyat al-ibdaa", color: 222 },
|
|
8786
|
+
{ text: "masdar maftuh", color: 228 }
|
|
8730
8787
|
];
|
|
8731
8788
|
Carousel = class {
|
|
8732
8789
|
rows;
|
|
8733
8790
|
timer = null;
|
|
8734
8791
|
width;
|
|
8735
8792
|
lineCount = 3;
|
|
8793
|
+
/** Total rows reserved at top: 3 carousel + 1 blank separator */
|
|
8794
|
+
reservedRows = 4;
|
|
8736
8795
|
started = false;
|
|
8737
8796
|
resizeHandler = null;
|
|
8738
8797
|
constructor() {
|
|
@@ -8742,11 +8801,8 @@ var init_carousel = __esm({
|
|
|
8742
8801
|
const indices2 = Array.from({ length: PHRASES.length }, (_, i) => i).sort(() => Math.random() - 0.5);
|
|
8743
8802
|
this.rows = [
|
|
8744
8803
|
createRow(indices0, 2, -1),
|
|
8745
|
-
// fast left
|
|
8746
8804
|
createRow(indices1, 1, 1),
|
|
8747
|
-
// medium right
|
|
8748
8805
|
createRow(indices2, 1.5, -1)
|
|
8749
|
-
// slow-medium left
|
|
8750
8806
|
];
|
|
8751
8807
|
this.rebuildRibbons();
|
|
8752
8808
|
}
|
|
@@ -8757,13 +8813,8 @@ var init_carousel = __esm({
|
|
|
8757
8813
|
}
|
|
8758
8814
|
/**
|
|
8759
8815
|
* Start the animation.
|
|
8760
|
-
*
|
|
8761
|
-
*
|
|
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.
|
|
8816
|
+
* Reserves rows 1-3 for carousel, row 4 as blank separator.
|
|
8817
|
+
* Sets scroll region to row 5+ for all content/readline.
|
|
8767
8818
|
*/
|
|
8768
8819
|
start() {
|
|
8769
8820
|
if (!isTTY3)
|
|
@@ -8771,17 +8822,17 @@ var init_carousel = __esm({
|
|
|
8771
8822
|
this.started = true;
|
|
8772
8823
|
const termRows = process.stdout.rows ?? 24;
|
|
8773
8824
|
process.stdout.write("\x1B[1;1H");
|
|
8774
|
-
for (let i = 0; i < this.
|
|
8825
|
+
for (let i = 0; i < this.reservedRows; i++) {
|
|
8775
8826
|
process.stdout.write("\x1B[2K\n");
|
|
8776
8827
|
}
|
|
8777
|
-
process.stdout.write(`\x1B[${this.
|
|
8778
|
-
process.stdout.write(`\x1B[${this.
|
|
8828
|
+
process.stdout.write(`\x1B[${this.reservedRows + 1};${termRows}r`);
|
|
8829
|
+
process.stdout.write(`\x1B[${this.reservedRows + 1};1H`);
|
|
8779
8830
|
this.resizeHandler = () => {
|
|
8780
8831
|
this.width = process.stdout.columns ?? 80;
|
|
8781
8832
|
const newRows = process.stdout.rows ?? 24;
|
|
8782
8833
|
this.rebuildRibbons();
|
|
8783
8834
|
if (this.started) {
|
|
8784
|
-
process.stdout.write(`\x1B[${this.
|
|
8835
|
+
process.stdout.write(`\x1B[${this.reservedRows + 1};${newRows}r`);
|
|
8785
8836
|
}
|
|
8786
8837
|
};
|
|
8787
8838
|
process.stdout.on("resize", this.resizeHandler);
|
|
@@ -8795,40 +8846,41 @@ var init_carousel = __esm({
|
|
|
8795
8846
|
}
|
|
8796
8847
|
this.renderFrame();
|
|
8797
8848
|
}, 66);
|
|
8798
|
-
return this.
|
|
8849
|
+
return this.reservedRows;
|
|
8799
8850
|
}
|
|
8800
8851
|
/**
|
|
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.
|
|
8852
|
+
* Render one animation frame into rows 1-3 only.
|
|
8853
|
+
* Row 4 is left blank as a separator.
|
|
8806
8854
|
*/
|
|
8807
8855
|
renderFrame() {
|
|
8808
8856
|
if (!isTTY3)
|
|
8809
8857
|
return;
|
|
8810
8858
|
let buf = "\x1B7";
|
|
8859
|
+
buf += "\x1B[?7l";
|
|
8811
8860
|
for (let i = 0; i < this.rows.length; i++) {
|
|
8812
8861
|
const line = this.extractWindow(this.rows[i]);
|
|
8813
8862
|
buf += `\x1B[${i + 1};1H\x1B[2K${line}`;
|
|
8814
8863
|
}
|
|
8864
|
+
buf += `\x1B[4;1H\x1B[2K`;
|
|
8865
|
+
buf += "\x1B[?7h";
|
|
8815
8866
|
buf += "\x1B8";
|
|
8816
8867
|
process.stdout.write(buf);
|
|
8817
8868
|
}
|
|
8818
8869
|
/**
|
|
8819
8870
|
* Extract a terminal-width colored window from a scrolling ribbon.
|
|
8871
|
+
* Uses column-aware width to prevent CJK/fullwidth character overflow.
|
|
8820
8872
|
*/
|
|
8821
8873
|
extractWindow(row) {
|
|
8822
|
-
const
|
|
8874
|
+
const maxCols = this.width;
|
|
8823
8875
|
const plain = row.renderedPlain;
|
|
8824
8876
|
if (!plain)
|
|
8825
8877
|
return "";
|
|
8826
8878
|
let start = Math.floor(Math.abs(row.offset)) % plain.length;
|
|
8827
8879
|
if (start < 0)
|
|
8828
8880
|
start += plain.length;
|
|
8829
|
-
const separator = "
|
|
8881
|
+
const separator = " : ";
|
|
8830
8882
|
let coloredLine = "";
|
|
8831
|
-
let
|
|
8883
|
+
let colCount = 0;
|
|
8832
8884
|
let charInPhrase = 0;
|
|
8833
8885
|
let skipChars = start;
|
|
8834
8886
|
const phrases = row.phrases;
|
|
@@ -8843,20 +8895,25 @@ var init_carousel = __esm({
|
|
|
8843
8895
|
skipChars -= fullText.length;
|
|
8844
8896
|
fullIdx++;
|
|
8845
8897
|
}
|
|
8846
|
-
while (
|
|
8898
|
+
while (colCount < maxCols) {
|
|
8847
8899
|
const p = phrases[fullIdx % phrases.length];
|
|
8848
8900
|
const fullText = p.text + separator;
|
|
8849
8901
|
const remaining = fullText.slice(charInPhrase);
|
|
8850
8902
|
for (const ch of remaining) {
|
|
8851
|
-
|
|
8903
|
+
const chWidth = displayWidth(ch);
|
|
8904
|
+
if (colCount + chWidth > maxCols) {
|
|
8905
|
+
if (colCount < maxCols)
|
|
8906
|
+
coloredLine += " ";
|
|
8907
|
+
colCount = maxCols;
|
|
8852
8908
|
break;
|
|
8909
|
+
}
|
|
8853
8910
|
const inPhrase = charInPhrase < p.text.length;
|
|
8854
8911
|
if (inPhrase) {
|
|
8855
8912
|
coloredLine += fg(p.color, ch);
|
|
8856
8913
|
} else {
|
|
8857
8914
|
coloredLine += `\x1B[2m${ch}\x1B[0m`;
|
|
8858
8915
|
}
|
|
8859
|
-
|
|
8916
|
+
colCount += chWidth;
|
|
8860
8917
|
charInPhrase++;
|
|
8861
8918
|
}
|
|
8862
8919
|
fullIdx++;
|
|
@@ -8865,7 +8922,7 @@ var init_carousel = __esm({
|
|
|
8865
8922
|
return coloredLine;
|
|
8866
8923
|
}
|
|
8867
8924
|
/**
|
|
8868
|
-
* Stop the animation, clear
|
|
8925
|
+
* Stop the animation, clear rows 1-4, reset scroll region.
|
|
8869
8926
|
*/
|
|
8870
8927
|
stop() {
|
|
8871
8928
|
if (this.timer) {
|
|
@@ -8879,7 +8936,7 @@ var init_carousel = __esm({
|
|
|
8879
8936
|
if (!isTTY3 || !this.started)
|
|
8880
8937
|
return;
|
|
8881
8938
|
let buf = "\x1B7";
|
|
8882
|
-
for (let i = 0; i < this.
|
|
8939
|
+
for (let i = 0; i < this.reservedRows; i++) {
|
|
8883
8940
|
buf += `\x1B[${i + 1};1H\x1B[2K`;
|
|
8884
8941
|
}
|
|
8885
8942
|
buf += "\x1B[r";
|
|
@@ -8887,7 +8944,6 @@ var init_carousel = __esm({
|
|
|
8887
8944
|
process.stdout.write(buf);
|
|
8888
8945
|
this.started = false;
|
|
8889
8946
|
}
|
|
8890
|
-
/** Check if carousel is running */
|
|
8891
8947
|
get isRunning() {
|
|
8892
8948
|
return this.timer !== null;
|
|
8893
8949
|
}
|
|
@@ -9666,6 +9722,10 @@ function startTask(task, config, repoRoot, voice) {
|
|
|
9666
9722
|
}
|
|
9667
9723
|
async function startInteractive(config, repoPath) {
|
|
9668
9724
|
const repoRoot = resolve11(repoPath ?? cwd());
|
|
9725
|
+
const isResumed = !!process.env.__OA_RESUMED;
|
|
9726
|
+
if (isResumed) {
|
|
9727
|
+
delete process.env.__OA_RESUMED;
|
|
9728
|
+
}
|
|
9669
9729
|
initOaDirectory(repoRoot);
|
|
9670
9730
|
const savedSettings = resolveSettings(repoRoot);
|
|
9671
9731
|
if (savedSettings.model)
|
|
@@ -9679,30 +9739,37 @@ async function startInteractive(config, repoPath) {
|
|
|
9679
9739
|
config = { ...config, apiKey: savedSettings.apiKey };
|
|
9680
9740
|
if (savedSettings.verbose !== void 0)
|
|
9681
9741
|
config = { ...config, verbose: savedSettings.verbose };
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9742
|
+
if (!isResumed) {
|
|
9743
|
+
const needsSetup = isFirstRun() || !await isModelAvailable(config);
|
|
9744
|
+
if (needsSetup && config.backendType === "ollama") {
|
|
9745
|
+
const setupModel = await runSetupWizard(config);
|
|
9746
|
+
if (setupModel === null) {
|
|
9747
|
+
process.exit(0);
|
|
9748
|
+
}
|
|
9749
|
+
config = { ...config, model: setupModel };
|
|
9687
9750
|
}
|
|
9688
|
-
config = { ...config, model: setupModel };
|
|
9689
9751
|
}
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9752
|
+
if (!isResumed) {
|
|
9753
|
+
try {
|
|
9754
|
+
const healthUrl = config.backendType === "ollama" ? `${config.backendUrl}/api/tags` : `${config.backendUrl}/v1/models`;
|
|
9755
|
+
const resp = await fetch(healthUrl, { signal: AbortSignal.timeout(1e4) });
|
|
9756
|
+
if (!resp.ok)
|
|
9757
|
+
throw new Error(`HTTP ${resp.status}`);
|
|
9758
|
+
} catch {
|
|
9759
|
+
renderError(`Cannot reach ${config.backendType} at ${config.backendUrl}`);
|
|
9760
|
+
if (config.backendType === "ollama") {
|
|
9761
|
+
renderInfo("Start Ollama with: ollama serve");
|
|
9762
|
+
}
|
|
9763
|
+
renderInfo("Use /endpoint to configure a different backend.");
|
|
9764
|
+
process.exit(1);
|
|
9699
9765
|
}
|
|
9700
|
-
renderInfo("Use /endpoint to configure a different backend.");
|
|
9701
|
-
process.exit(1);
|
|
9702
9766
|
}
|
|
9703
9767
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
9704
9768
|
const carousel = new Carousel();
|
|
9705
|
-
|
|
9769
|
+
let carouselLines = 0;
|
|
9770
|
+
if (!isResumed) {
|
|
9771
|
+
carouselLines = carousel.start();
|
|
9772
|
+
}
|
|
9706
9773
|
const version = getVersion();
|
|
9707
9774
|
renderRichHeader({
|
|
9708
9775
|
model: config.model,
|
|
@@ -9710,6 +9777,10 @@ async function startInteractive(config, repoPath) {
|
|
|
9710
9777
|
workspace: repoRoot,
|
|
9711
9778
|
carouselLines
|
|
9712
9779
|
});
|
|
9780
|
+
if (isResumed) {
|
|
9781
|
+
renderInfo(`Auto-updated to v${version} \u2014 session resumed.
|
|
9782
|
+
`);
|
|
9783
|
+
}
|
|
9713
9784
|
const voiceEngine = new VoiceEngine();
|
|
9714
9785
|
if (savedSettings.voice) {
|
|
9715
9786
|
voiceEngine.toggle().catch(() => {
|
|
@@ -9722,7 +9793,7 @@ async function startInteractive(config, repoPath) {
|
|
|
9722
9793
|
let currentConfig = { ...config };
|
|
9723
9794
|
let activeTask = null;
|
|
9724
9795
|
let messageQueue = [];
|
|
9725
|
-
let carouselRetired =
|
|
9796
|
+
let carouselRetired = isResumed;
|
|
9726
9797
|
const idlePrompt = `${c2.bold(c2.blue("> "))}`;
|
|
9727
9798
|
const activePrompt = `${c2.dim(c2.cyan("+ "))}`;
|
|
9728
9799
|
const rl = readline2.createInterface({
|
|
@@ -9735,8 +9806,9 @@ async function startInteractive(config, repoPath) {
|
|
|
9735
9806
|
process.stdout.on("resize", () => {
|
|
9736
9807
|
if (!carouselRetired) {
|
|
9737
9808
|
const termRows = process.stdout.rows ?? 24;
|
|
9738
|
-
|
|
9739
|
-
process.stdout.write(`\x1B[${
|
|
9809
|
+
const scrollStart = carousel.reservedRows + 1;
|
|
9810
|
+
process.stdout.write(`\x1B[${scrollStart};${termRows}r`);
|
|
9811
|
+
process.stdout.write(`\x1B[${scrollStart};1H\x1B[J`);
|
|
9740
9812
|
renderRichHeader({
|
|
9741
9813
|
model: currentConfig.model,
|
|
9742
9814
|
version,
|
|
@@ -9863,6 +9935,26 @@ ${c2.dim("Goodbye!")}
|
|
|
9863
9935
|
} finally {
|
|
9864
9936
|
activeTask = null;
|
|
9865
9937
|
}
|
|
9938
|
+
try {
|
|
9939
|
+
const updateInfo = await checkForUpdate(version);
|
|
9940
|
+
if (updateInfo) {
|
|
9941
|
+
renderInfo(`Update available: v${version} \u2192 v${updateInfo.latestVersion}. Installing...`);
|
|
9942
|
+
const ok = performSilentUpdate();
|
|
9943
|
+
if (ok) {
|
|
9944
|
+
renderInfo(`Updated to v${updateInfo.latestVersion}. Reloading...
|
|
9945
|
+
`);
|
|
9946
|
+
process.env.__OA_RESUMED = "1";
|
|
9947
|
+
if (carousel.isRunning)
|
|
9948
|
+
carousel.stop();
|
|
9949
|
+
voiceEngine.dispose();
|
|
9950
|
+
rl.close();
|
|
9951
|
+
restartProcess();
|
|
9952
|
+
} else {
|
|
9953
|
+
renderWarning("Auto-update failed. Use /update to retry manually.");
|
|
9954
|
+
}
|
|
9955
|
+
}
|
|
9956
|
+
} catch {
|
|
9957
|
+
}
|
|
9866
9958
|
showPrompt();
|
|
9867
9959
|
});
|
|
9868
9960
|
rl.on("close", () => {
|
|
@@ -9922,6 +10014,7 @@ var init_interactive = __esm({
|
|
|
9922
10014
|
"use strict";
|
|
9923
10015
|
init_dist5();
|
|
9924
10016
|
init_dist2();
|
|
10017
|
+
init_updater();
|
|
9925
10018
|
init_commands();
|
|
9926
10019
|
init_setup();
|
|
9927
10020
|
init_project_context();
|
package/package.json
CHANGED