open-agents-ai 0.30.3 → 0.30.5
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 +335 -37
- package/dist/launcher.cjs +17 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -105,7 +105,7 @@ var init_config = __esm({
|
|
|
105
105
|
"packages/cli/dist/config.js"() {
|
|
106
106
|
"use strict";
|
|
107
107
|
DEFAULT_CONFIG = Object.freeze({
|
|
108
|
-
backendUrl: "http://
|
|
108
|
+
backendUrl: "http://127.0.0.1:11434",
|
|
109
109
|
model: "qwen3.5:latest",
|
|
110
110
|
backendType: "ollama",
|
|
111
111
|
apiKey: "",
|
|
@@ -6757,7 +6757,7 @@ Coordinates are normalized (0-1). Multiply by image width/height for pixel value
|
|
|
6757
6757
|
}
|
|
6758
6758
|
}
|
|
6759
6759
|
async tryOllamaVision(buffer, filename, action, prompt, length, start) {
|
|
6760
|
-
const ollamaHost = process.env["OLLAMA_HOST"] || "http://
|
|
6760
|
+
const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
6761
6761
|
const envModel = process.env["OLLAMA_VISION_MODEL"];
|
|
6762
6762
|
const model = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
|
|
6763
6763
|
const imageBase64 = buffer.toString("base64");
|
|
@@ -7079,7 +7079,7 @@ var init_desktop_click = __esm({
|
|
|
7079
7079
|
}
|
|
7080
7080
|
if (!visionWorked) {
|
|
7081
7081
|
try {
|
|
7082
|
-
const ollamaHost = process.env["OLLAMA_HOST"] || "http://
|
|
7082
|
+
const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
7083
7083
|
const envModel = process.env["OLLAMA_VISION_MODEL"];
|
|
7084
7084
|
const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
|
|
7085
7085
|
const imageBase64 = readFileSync11(screenshotPath).toString("base64");
|
|
@@ -7253,7 +7253,7 @@ ${caption}`);
|
|
|
7253
7253
|
}
|
|
7254
7254
|
if (!visionWorked) {
|
|
7255
7255
|
try {
|
|
7256
|
-
const ollamaHost = process.env["OLLAMA_HOST"] || "http://
|
|
7256
|
+
const ollamaHost = process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
|
|
7257
7257
|
const envModel = process.env["OLLAMA_VISION_MODEL"];
|
|
7258
7258
|
const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
|
|
7259
7259
|
const imageBase64 = imageBuffer.toString("base64");
|
|
@@ -10343,6 +10343,8 @@ Rules:
|
|
|
10343
10343
|
handlers = [];
|
|
10344
10344
|
pendingUserMessages = [];
|
|
10345
10345
|
aborted = false;
|
|
10346
|
+
_paused = false;
|
|
10347
|
+
_pauseResolve = null;
|
|
10346
10348
|
_sudoPassword = null;
|
|
10347
10349
|
_sudoResolve = null;
|
|
10348
10350
|
constructor(backend, options) {
|
|
@@ -10388,6 +10390,50 @@ Rules:
|
|
|
10388
10390
|
/** Abort the current task run */
|
|
10389
10391
|
abort() {
|
|
10390
10392
|
this.aborted = true;
|
|
10393
|
+
if (this._pauseResolve) {
|
|
10394
|
+
this._pauseResolve();
|
|
10395
|
+
this._pauseResolve = null;
|
|
10396
|
+
}
|
|
10397
|
+
}
|
|
10398
|
+
/**
|
|
10399
|
+
* Pause the current task gracefully. The run loop will suspend at the next
|
|
10400
|
+
* turn boundary (between tool calls / model requests) without destroying state.
|
|
10401
|
+
* Call resume() to continue.
|
|
10402
|
+
*/
|
|
10403
|
+
pause() {
|
|
10404
|
+
if (!this._paused) {
|
|
10405
|
+
this._paused = true;
|
|
10406
|
+
this.emit({ type: "compaction", content: "Task paused by user.", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10407
|
+
}
|
|
10408
|
+
}
|
|
10409
|
+
/**
|
|
10410
|
+
* Resume a paused task. The run loop continues from where it left off.
|
|
10411
|
+
*/
|
|
10412
|
+
resume() {
|
|
10413
|
+
if (this._paused) {
|
|
10414
|
+
this._paused = false;
|
|
10415
|
+
this.emit({ type: "compaction", content: "Task resumed by user.", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10416
|
+
if (this._pauseResolve) {
|
|
10417
|
+
this._pauseResolve();
|
|
10418
|
+
this._pauseResolve = null;
|
|
10419
|
+
}
|
|
10420
|
+
}
|
|
10421
|
+
}
|
|
10422
|
+
/** Whether the runner is currently paused */
|
|
10423
|
+
get isPaused() {
|
|
10424
|
+
return this._paused;
|
|
10425
|
+
}
|
|
10426
|
+
/**
|
|
10427
|
+
* If paused, block until resume() or abort() is called.
|
|
10428
|
+
* Returns true if the loop should continue, false if aborted while paused.
|
|
10429
|
+
*/
|
|
10430
|
+
async waitIfPaused() {
|
|
10431
|
+
if (!this._paused)
|
|
10432
|
+
return true;
|
|
10433
|
+
await new Promise((resolve19) => {
|
|
10434
|
+
this._pauseResolve = resolve19;
|
|
10435
|
+
});
|
|
10436
|
+
return !this.aborted;
|
|
10391
10437
|
}
|
|
10392
10438
|
emit(event) {
|
|
10393
10439
|
for (const handler of this.handlers) {
|
|
@@ -10440,6 +10486,8 @@ Respond with your assessment, then take action.`;
|
|
|
10440
10486
|
let selfEvalCount = 0;
|
|
10441
10487
|
const toolCallLog = [];
|
|
10442
10488
|
this.aborted = false;
|
|
10489
|
+
this._paused = false;
|
|
10490
|
+
this._pauseResolve = null;
|
|
10443
10491
|
this.pendingUserMessages.length = 0;
|
|
10444
10492
|
const basePrompt = getSystemPromptForTier(this.options.modelTier);
|
|
10445
10493
|
const systemPrompt = this.options.dynamicContext ? `${basePrompt}
|
|
@@ -10461,6 +10509,13 @@ TASK: ${task}` : task }
|
|
|
10461
10509
|
let summary = "";
|
|
10462
10510
|
let bruteForceCycle = 0;
|
|
10463
10511
|
for (let turn = 0; turn < this.options.maxTurns; turn++) {
|
|
10512
|
+
if (this._paused) {
|
|
10513
|
+
const shouldContinue = await this.waitIfPaused();
|
|
10514
|
+
if (!shouldContinue) {
|
|
10515
|
+
this.emit({ type: "error", content: "Task aborted by user", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10516
|
+
break;
|
|
10517
|
+
}
|
|
10518
|
+
}
|
|
10464
10519
|
if (this.aborted) {
|
|
10465
10520
|
this.emit({ type: "error", content: "Task aborted by user", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10466
10521
|
break;
|
|
@@ -10717,6 +10772,13 @@ You have ${this.options.maxTurns} more turns. Continue making progress. Call tas
|
|
|
10717
10772
|
messages.push(...compacted);
|
|
10718
10773
|
}
|
|
10719
10774
|
for (let turn = 0; turn < this.options.maxTurns; turn++) {
|
|
10775
|
+
if (this._paused) {
|
|
10776
|
+
const shouldContinue = await this.waitIfPaused();
|
|
10777
|
+
if (!shouldContinue) {
|
|
10778
|
+
this.emit({ type: "error", content: "Task aborted by user", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10779
|
+
break;
|
|
10780
|
+
}
|
|
10781
|
+
}
|
|
10720
10782
|
if (this.aborted) {
|
|
10721
10783
|
this.emit({ type: "error", content: "Task aborted by user", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10722
10784
|
break;
|
|
@@ -12061,8 +12123,8 @@ function isTranscribablePath(path) {
|
|
|
12061
12123
|
return isAudioPath(path) || isVideoPath(path);
|
|
12062
12124
|
}
|
|
12063
12125
|
function findMicCaptureCommand() {
|
|
12064
|
-
const
|
|
12065
|
-
if (
|
|
12126
|
+
const platform4 = process.platform;
|
|
12127
|
+
if (platform4 === "linux") {
|
|
12066
12128
|
try {
|
|
12067
12129
|
execSync12("which arecord", { stdio: "pipe" });
|
|
12068
12130
|
return {
|
|
@@ -12072,7 +12134,7 @@ function findMicCaptureCommand() {
|
|
|
12072
12134
|
} catch {
|
|
12073
12135
|
}
|
|
12074
12136
|
}
|
|
12075
|
-
if (
|
|
12137
|
+
if (platform4 === "darwin") {
|
|
12076
12138
|
try {
|
|
12077
12139
|
execSync12("which sox", { stdio: "pipe" });
|
|
12078
12140
|
return {
|
|
@@ -12084,7 +12146,7 @@ function findMicCaptureCommand() {
|
|
|
12084
12146
|
}
|
|
12085
12147
|
try {
|
|
12086
12148
|
execSync12("which ffmpeg", { stdio: "pipe" });
|
|
12087
|
-
if (
|
|
12149
|
+
if (platform4 === "linux") {
|
|
12088
12150
|
return {
|
|
12089
12151
|
cmd: "ffmpeg",
|
|
12090
12152
|
args: [
|
|
@@ -12103,7 +12165,7 @@ function findMicCaptureCommand() {
|
|
|
12103
12165
|
"pipe:1"
|
|
12104
12166
|
]
|
|
12105
12167
|
};
|
|
12106
|
-
} else if (
|
|
12168
|
+
} else if (platform4 === "darwin") {
|
|
12107
12169
|
return {
|
|
12108
12170
|
cmd: "ffmpeg",
|
|
12109
12171
|
args: [
|
|
@@ -14272,10 +14334,10 @@ var init_oa_directory = __esm({
|
|
|
14272
14334
|
|
|
14273
14335
|
// packages/cli/dist/tui/setup.js
|
|
14274
14336
|
import * as readline from "node:readline";
|
|
14275
|
-
import { execSync as execSync13 } from "node:child_process";
|
|
14337
|
+
import { execSync as execSync13, spawn as spawn8 } from "node:child_process";
|
|
14276
14338
|
import { existsSync as existsSync15, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "node:fs";
|
|
14277
14339
|
import { join as join22 } from "node:path";
|
|
14278
|
-
import { homedir as homedir8 } from "node:os";
|
|
14340
|
+
import { homedir as homedir8, platform } from "node:os";
|
|
14279
14341
|
function detectSystemSpecs() {
|
|
14280
14342
|
let totalRamGB = 0;
|
|
14281
14343
|
let availableRamGB = 0;
|
|
@@ -14362,6 +14424,148 @@ function ask(rl, question) {
|
|
|
14362
14424
|
rl.question(question, (answer) => resolve19(answer.trim()));
|
|
14363
14425
|
});
|
|
14364
14426
|
}
|
|
14427
|
+
async function autoInstallOllama(rl) {
|
|
14428
|
+
const plat = platform();
|
|
14429
|
+
if (plat === "linux") {
|
|
14430
|
+
return installOllamaLinux();
|
|
14431
|
+
} else if (plat === "darwin") {
|
|
14432
|
+
return await installOllamaMac(rl);
|
|
14433
|
+
} else if (plat === "win32") {
|
|
14434
|
+
return installOllamaWindows();
|
|
14435
|
+
}
|
|
14436
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} Unsupported platform: ${plat}
|
|
14437
|
+
`);
|
|
14438
|
+
process.stdout.write(` ${c2.dim("Visit https://ollama.com to install manually.")}
|
|
14439
|
+
|
|
14440
|
+
`);
|
|
14441
|
+
return false;
|
|
14442
|
+
}
|
|
14443
|
+
function installOllamaLinux() {
|
|
14444
|
+
process.stdout.write(`
|
|
14445
|
+
${c2.cyan("\u25CF")} Installing Ollama via official install script...
|
|
14446
|
+
|
|
14447
|
+
`);
|
|
14448
|
+
try {
|
|
14449
|
+
execSync13("curl -fsSL https://ollama.com/install.sh | sh", {
|
|
14450
|
+
stdio: "inherit",
|
|
14451
|
+
timeout: 3e5
|
|
14452
|
+
});
|
|
14453
|
+
if (hasCmd("ollama")) {
|
|
14454
|
+
process.stdout.write(`
|
|
14455
|
+
${c2.green("\u2714")} Ollama installed successfully.
|
|
14456
|
+
`);
|
|
14457
|
+
return true;
|
|
14458
|
+
}
|
|
14459
|
+
process.stdout.write(`
|
|
14460
|
+
${c2.yellow("\u26A0")} Install script ran but ollama not found on PATH.
|
|
14461
|
+
`);
|
|
14462
|
+
return false;
|
|
14463
|
+
} catch (err) {
|
|
14464
|
+
process.stdout.write(`
|
|
14465
|
+
${c2.red("\u2716")} Ollama install failed: ${err instanceof Error ? err.message : String(err)}
|
|
14466
|
+
`);
|
|
14467
|
+
return false;
|
|
14468
|
+
}
|
|
14469
|
+
}
|
|
14470
|
+
async function installOllamaMac(rl) {
|
|
14471
|
+
if (!hasCmd("brew")) {
|
|
14472
|
+
process.stdout.write(`
|
|
14473
|
+
${c2.yellow("\u26A0")} Homebrew is not installed (needed for Ollama on macOS).
|
|
14474
|
+
|
|
14475
|
+
`);
|
|
14476
|
+
const installBrew = await ask(rl, ` ${c2.bold("Install Homebrew?")} (Y/n) `);
|
|
14477
|
+
if (installBrew.toLowerCase() === "n") {
|
|
14478
|
+
process.stdout.write(` ${c2.dim("Skipping Homebrew install.")}
|
|
14479
|
+
|
|
14480
|
+
`);
|
|
14481
|
+
return false;
|
|
14482
|
+
}
|
|
14483
|
+
process.stdout.write(`
|
|
14484
|
+
${c2.cyan("\u25CF")} Installing Homebrew...
|
|
14485
|
+
|
|
14486
|
+
`);
|
|
14487
|
+
try {
|
|
14488
|
+
execSync13('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
|
|
14489
|
+
if (!hasCmd("brew")) {
|
|
14490
|
+
try {
|
|
14491
|
+
const brewPrefix = existsSync15("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
|
|
14492
|
+
process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
|
|
14493
|
+
} catch {
|
|
14494
|
+
}
|
|
14495
|
+
}
|
|
14496
|
+
if (hasCmd("brew")) {
|
|
14497
|
+
process.stdout.write(`
|
|
14498
|
+
${c2.green("\u2714")} Homebrew installed.
|
|
14499
|
+
`);
|
|
14500
|
+
} else {
|
|
14501
|
+
process.stdout.write(`
|
|
14502
|
+
${c2.yellow("\u26A0")} Homebrew install completed but brew not found on PATH.
|
|
14503
|
+
`);
|
|
14504
|
+
process.stdout.write(` ${c2.dim('Try: eval "$(/opt/homebrew/bin/brew shellenv)"')}
|
|
14505
|
+
|
|
14506
|
+
`);
|
|
14507
|
+
return false;
|
|
14508
|
+
}
|
|
14509
|
+
} catch (err) {
|
|
14510
|
+
process.stdout.write(`
|
|
14511
|
+
${c2.red("\u2716")} Homebrew install failed: ${err instanceof Error ? err.message : String(err)}
|
|
14512
|
+
`);
|
|
14513
|
+
return false;
|
|
14514
|
+
}
|
|
14515
|
+
}
|
|
14516
|
+
process.stdout.write(`
|
|
14517
|
+
${c2.cyan("\u25CF")} Installing Ollama via Homebrew...
|
|
14518
|
+
|
|
14519
|
+
`);
|
|
14520
|
+
try {
|
|
14521
|
+
execSync13("brew install ollama", {
|
|
14522
|
+
stdio: "inherit",
|
|
14523
|
+
timeout: 3e5
|
|
14524
|
+
});
|
|
14525
|
+
if (hasCmd("ollama")) {
|
|
14526
|
+
process.stdout.write(`
|
|
14527
|
+
${c2.green("\u2714")} Ollama installed successfully.
|
|
14528
|
+
`);
|
|
14529
|
+
return true;
|
|
14530
|
+
}
|
|
14531
|
+
process.stdout.write(`
|
|
14532
|
+
${c2.yellow("\u26A0")} brew install completed but ollama not found on PATH.
|
|
14533
|
+
`);
|
|
14534
|
+
return false;
|
|
14535
|
+
} catch (err) {
|
|
14536
|
+
process.stdout.write(`
|
|
14537
|
+
${c2.red("\u2716")} Ollama install failed: ${err instanceof Error ? err.message : String(err)}
|
|
14538
|
+
`);
|
|
14539
|
+
return false;
|
|
14540
|
+
}
|
|
14541
|
+
}
|
|
14542
|
+
function installOllamaWindows() {
|
|
14543
|
+
process.stdout.write(`
|
|
14544
|
+
${c2.cyan("\u25CF")} Installing Ollama via PowerShell...
|
|
14545
|
+
|
|
14546
|
+
`);
|
|
14547
|
+
try {
|
|
14548
|
+
execSync13('powershell -Command "irm https://ollama.com/install.ps1 | iex"', {
|
|
14549
|
+
stdio: "inherit",
|
|
14550
|
+
timeout: 3e5
|
|
14551
|
+
});
|
|
14552
|
+
if (hasCmd("ollama")) {
|
|
14553
|
+
process.stdout.write(`
|
|
14554
|
+
${c2.green("\u2714")} Ollama installed successfully.
|
|
14555
|
+
`);
|
|
14556
|
+
return true;
|
|
14557
|
+
}
|
|
14558
|
+
process.stdout.write(`
|
|
14559
|
+
${c2.yellow("\u26A0")} Install script ran but ollama not found on PATH.
|
|
14560
|
+
`);
|
|
14561
|
+
return false;
|
|
14562
|
+
} catch (err) {
|
|
14563
|
+
process.stdout.write(`
|
|
14564
|
+
${c2.red("\u2716")} Ollama install failed: ${err instanceof Error ? err.message : String(err)}
|
|
14565
|
+
`);
|
|
14566
|
+
return false;
|
|
14567
|
+
}
|
|
14568
|
+
}
|
|
14365
14569
|
function pullModelWithAutoUpdate(tag) {
|
|
14366
14570
|
try {
|
|
14367
14571
|
execSync13(`ollama pull ${tag}`, {
|
|
@@ -14562,32 +14766,81 @@ async function doSetup(config, rl) {
|
|
|
14562
14766
|
process.stdout.write(` ${c2.yellow("\u26A0")} Cannot reach Ollama at ${c2.bold(config.backendUrl)}
|
|
14563
14767
|
|
|
14564
14768
|
`);
|
|
14565
|
-
const
|
|
14566
|
-
if (
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14769
|
+
const ollamaInstalled = hasCmd("ollama");
|
|
14770
|
+
if (ollamaInstalled) {
|
|
14771
|
+
process.stdout.write(` ${c2.cyan("\u25CF")} Ollama is installed but not running.
|
|
14772
|
+
|
|
14773
|
+
`);
|
|
14774
|
+
const startOllama = await ask(rl, ` ${c2.bold("Start Ollama now?")} (Y/n) `);
|
|
14775
|
+
if (startOllama.toLowerCase() !== "n") {
|
|
14776
|
+
process.stdout.write(`
|
|
14777
|
+
${c2.cyan("\u25CF")} Starting ollama serve in background...
|
|
14778
|
+
`);
|
|
14779
|
+
try {
|
|
14780
|
+
const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
14781
|
+
child.unref();
|
|
14782
|
+
await new Promise((resolve19) => setTimeout(resolve19, 3e3));
|
|
14783
|
+
try {
|
|
14784
|
+
models = await fetchOllamaModels(config.backendUrl);
|
|
14785
|
+
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
14786
|
+
|
|
14787
|
+
`);
|
|
14788
|
+
} catch {
|
|
14789
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} Ollama started but not responding yet. It may need a moment.
|
|
14790
|
+
|
|
14791
|
+
`);
|
|
14792
|
+
}
|
|
14793
|
+
} catch {
|
|
14794
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} Could not start Ollama. Try running ${c2.bold("ollama serve")} manually.
|
|
14795
|
+
|
|
14796
|
+
`);
|
|
14797
|
+
}
|
|
14570
14798
|
}
|
|
14571
|
-
usingCustomEndpoint = true;
|
|
14572
14799
|
} else {
|
|
14573
|
-
|
|
14574
|
-
|
|
14800
|
+
const installOllama = await ask(rl, ` ${c2.bold("Install Ollama?")} (Y/n) `);
|
|
14801
|
+
if (installOllama.toLowerCase() !== "n") {
|
|
14802
|
+
const installed = await autoInstallOllama(rl);
|
|
14803
|
+
if (installed) {
|
|
14804
|
+
process.stdout.write(`
|
|
14805
|
+
${c2.cyan("\u25CF")} Starting ollama serve...
|
|
14575
14806
|
`);
|
|
14576
|
-
|
|
14807
|
+
try {
|
|
14808
|
+
const child = spawn8("ollama", ["serve"], { stdio: "ignore", detached: true });
|
|
14809
|
+
child.unref();
|
|
14810
|
+
await new Promise((resolve19) => setTimeout(resolve19, 3e3));
|
|
14811
|
+
try {
|
|
14812
|
+
models = await fetchOllamaModels(config.backendUrl);
|
|
14813
|
+
process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
|
|
14814
|
+
|
|
14577
14815
|
`);
|
|
14578
|
-
|
|
14816
|
+
} catch {
|
|
14817
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} Ollama installed but not responding yet. Try ${c2.bold("ollama serve")} manually.
|
|
14818
|
+
|
|
14579
14819
|
`);
|
|
14580
|
-
|
|
14820
|
+
}
|
|
14821
|
+
} catch {
|
|
14822
|
+
process.stdout.write(` ${c2.yellow("\u26A0")} Ollama installed. Start it with: ${c2.bold("ollama serve")}
|
|
14581
14823
|
|
|
14582
14824
|
`);
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14825
|
+
}
|
|
14826
|
+
}
|
|
14827
|
+
}
|
|
14828
|
+
if (models.length === 0) {
|
|
14829
|
+
const useCustom = await ask(rl, ` ${c2.bold("Use a custom inference endpoint instead?")} (y/n) `);
|
|
14830
|
+
if (useCustom.toLowerCase() === "y" || useCustom.toLowerCase() === "yes") {
|
|
14831
|
+
const endpointResult = await promptForCustomEndpoint(config, rl);
|
|
14832
|
+
if (endpointResult) {
|
|
14833
|
+
return endpointResult;
|
|
14834
|
+
}
|
|
14835
|
+
usingCustomEndpoint = true;
|
|
14836
|
+
} else {
|
|
14837
|
+
process.stdout.write(`
|
|
14838
|
+
${c2.dim("You can configure an endpoint later with /endpoint")}
|
|
14587
14839
|
|
|
14588
14840
|
`);
|
|
14841
|
+
return config.model;
|
|
14842
|
+
}
|
|
14589
14843
|
}
|
|
14590
|
-
return config.model;
|
|
14591
14844
|
}
|
|
14592
14845
|
}
|
|
14593
14846
|
if (usingCustomEndpoint) {
|
|
@@ -15489,8 +15742,24 @@ async function handleSlashCommand(input, ctx) {
|
|
|
15489
15742
|
renderInfo(`Colors ${next ? "enabled" : "disabled"}.`);
|
|
15490
15743
|
return "handled";
|
|
15491
15744
|
}
|
|
15492
|
-
case "stop":
|
|
15493
15745
|
case "pause": {
|
|
15746
|
+
if (!ctx.hasActiveTask?.()) {
|
|
15747
|
+
renderWarning("No active task to pause.");
|
|
15748
|
+
return "handled";
|
|
15749
|
+
}
|
|
15750
|
+
if (ctx.isTaskPaused?.()) {
|
|
15751
|
+
renderWarning("Task is already paused. Use /resume to continue.");
|
|
15752
|
+
return "handled";
|
|
15753
|
+
}
|
|
15754
|
+
const paused = ctx.pauseTask?.() ?? false;
|
|
15755
|
+
if (paused) {
|
|
15756
|
+
renderInfo("Task paused. Use /resume to continue or /stop to abort.");
|
|
15757
|
+
} else {
|
|
15758
|
+
renderWarning("Could not pause the task.");
|
|
15759
|
+
}
|
|
15760
|
+
return "handled";
|
|
15761
|
+
}
|
|
15762
|
+
case "stop": {
|
|
15494
15763
|
if (!ctx.hasActiveTask?.()) {
|
|
15495
15764
|
renderWarning("No active task to stop.");
|
|
15496
15765
|
return "handled";
|
|
@@ -15507,8 +15776,17 @@ async function handleSlashCommand(input, ctx) {
|
|
|
15507
15776
|
return "handled";
|
|
15508
15777
|
}
|
|
15509
15778
|
case "resume": {
|
|
15779
|
+
if (ctx.isTaskPaused?.()) {
|
|
15780
|
+
const resumed2 = ctx.resumeInSessionTask?.() ?? false;
|
|
15781
|
+
if (resumed2) {
|
|
15782
|
+
renderInfo("Task resumed.");
|
|
15783
|
+
} else {
|
|
15784
|
+
renderWarning("Could not resume the paused task.");
|
|
15785
|
+
}
|
|
15786
|
+
return "handled";
|
|
15787
|
+
}
|
|
15510
15788
|
if (ctx.hasActiveTask?.()) {
|
|
15511
|
-
renderWarning("A task is already running.
|
|
15789
|
+
renderWarning("A task is already running. Pause it first with /pause or stop with /stop.");
|
|
15512
15790
|
return "handled";
|
|
15513
15791
|
}
|
|
15514
15792
|
const resumed = ctx.resumeTask?.() ?? false;
|
|
@@ -15570,7 +15848,7 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
15570
15848
|
process.stdout.write(`
|
|
15571
15849
|
${c2.dim("Usage: /endpoint <url> [--auth <token>]")}
|
|
15572
15850
|
`);
|
|
15573
|
-
process.stdout.write(` ${c2.dim(" /endpoint http://
|
|
15851
|
+
process.stdout.write(` ${c2.dim(" /endpoint http://127.0.0.1:11434 Ollama")}
|
|
15574
15852
|
`);
|
|
15575
15853
|
process.stdout.write(` ${c2.dim(" /endpoint https://llm.chutes.ai --auth cpk_... Chutes AI")}
|
|
15576
15854
|
`);
|
|
@@ -15803,7 +16081,7 @@ var init_commands = __esm({
|
|
|
15803
16081
|
import { existsSync as existsSync16, readFileSync as readFileSync13, readdirSync as readdirSync8 } from "node:fs";
|
|
15804
16082
|
import { join as join23, basename as basename6 } from "node:path";
|
|
15805
16083
|
import { execSync as execSync14 } from "node:child_process";
|
|
15806
|
-
import { homedir as homedir9, platform, release } from "node:os";
|
|
16084
|
+
import { homedir as homedir9, platform as platform2, release } from "node:os";
|
|
15807
16085
|
function getModelTier(modelName) {
|
|
15808
16086
|
const m = modelName.toLowerCase();
|
|
15809
16087
|
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
@@ -15943,7 +16221,7 @@ function getEnvironment(repoRoot) {
|
|
|
15943
16221
|
const lines = [
|
|
15944
16222
|
`Working directory: ${repoRoot}`,
|
|
15945
16223
|
`Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
|
|
15946
|
-
`Platform: ${
|
|
16224
|
+
`Platform: ${platform2()} ${release()}`,
|
|
15947
16225
|
`Node: ${process.version}`
|
|
15948
16226
|
];
|
|
15949
16227
|
return lines.join("\n");
|
|
@@ -17284,7 +17562,7 @@ var init_carousel_descriptors = __esm({
|
|
|
17284
17562
|
// packages/cli/dist/tui/voice.js
|
|
17285
17563
|
import { existsSync as existsSync18, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync15, unlinkSync as unlinkSync3 } from "node:fs";
|
|
17286
17564
|
import { join as join25 } from "node:path";
|
|
17287
|
-
import { homedir as homedir10, tmpdir as tmpdir4, platform as
|
|
17565
|
+
import { homedir as homedir10, tmpdir as tmpdir4, platform as platform3 } from "node:os";
|
|
17288
17566
|
import { execSync as execSync15, spawn as nodeSpawn } from "node:child_process";
|
|
17289
17567
|
import { createRequire } from "node:module";
|
|
17290
17568
|
function voiceDir() {
|
|
@@ -17691,7 +17969,7 @@ var init_voice = __esm({
|
|
|
17691
17969
|
});
|
|
17692
17970
|
}
|
|
17693
17971
|
getPlayCommand(path) {
|
|
17694
|
-
const os =
|
|
17972
|
+
const os = platform3();
|
|
17695
17973
|
if (os === "darwin")
|
|
17696
17974
|
return ["afplay", path];
|
|
17697
17975
|
if (os === "win32") {
|
|
@@ -20474,6 +20752,7 @@ async function startInteractive(config, repoPath) {
|
|
|
20474
20752
|
let sudoPromptPending = false;
|
|
20475
20753
|
const idlePrompt = `${c2.bold(c2.white("\u276F "))}`;
|
|
20476
20754
|
const activePrompt = `${c2.bold(c2.white("+ "))}`;
|
|
20755
|
+
const pausedPrompt = `${c2.bold(c2.yellow("| "))}`;
|
|
20477
20756
|
const rl = readline2.createInterface({
|
|
20478
20757
|
input: process.stdin,
|
|
20479
20758
|
output: process.stdout,
|
|
@@ -20507,7 +20786,7 @@ async function startInteractive(config, repoPath) {
|
|
|
20507
20786
|
}
|
|
20508
20787
|
});
|
|
20509
20788
|
function showPrompt() {
|
|
20510
|
-
const prompt = activeTask ? activePrompt : idlePrompt;
|
|
20789
|
+
const prompt = activeTask ? activeTask.runner.isPaused ? pausedPrompt : activePrompt : idlePrompt;
|
|
20511
20790
|
rl.setPrompt(prompt);
|
|
20512
20791
|
if (statusBar.isActive) {
|
|
20513
20792
|
statusBar.setPromptText(prompt, 2);
|
|
@@ -20759,6 +21038,25 @@ async function startInteractive(config, repoPath) {
|
|
|
20759
21038
|
writeContent(() => renderInfo("Task aborted."));
|
|
20760
21039
|
return true;
|
|
20761
21040
|
},
|
|
21041
|
+
pauseTask() {
|
|
21042
|
+
if (!activeTask)
|
|
21043
|
+
return false;
|
|
21044
|
+
activeTask.runner.pause();
|
|
21045
|
+
statusBar.setProcessing(false);
|
|
21046
|
+
showPrompt();
|
|
21047
|
+
return true;
|
|
21048
|
+
},
|
|
21049
|
+
resumeInSessionTask() {
|
|
21050
|
+
if (!activeTask || !activeTask.runner.isPaused)
|
|
21051
|
+
return false;
|
|
21052
|
+
activeTask.runner.resume();
|
|
21053
|
+
statusBar.setProcessing(true);
|
|
21054
|
+
showPrompt();
|
|
21055
|
+
return true;
|
|
21056
|
+
},
|
|
21057
|
+
isTaskPaused() {
|
|
21058
|
+
return activeTask !== null && activeTask.runner.isPaused;
|
|
21059
|
+
},
|
|
20762
21060
|
resumeTask() {
|
|
20763
21061
|
const pendingTask = loadPendingTask(repoRoot);
|
|
20764
21062
|
if (!pendingTask)
|
|
@@ -21790,7 +22088,7 @@ var serve_exports = {};
|
|
|
21790
22088
|
__export(serve_exports, {
|
|
21791
22089
|
serveCommand: () => serveCommand
|
|
21792
22090
|
});
|
|
21793
|
-
import { spawn as
|
|
22091
|
+
import { spawn as spawn9 } from "node:child_process";
|
|
21794
22092
|
async function serveCommand(opts, config) {
|
|
21795
22093
|
const backendType = config.backendType;
|
|
21796
22094
|
if (backendType === "ollama") {
|
|
@@ -21883,7 +22181,7 @@ async function serveVllm(opts, config) {
|
|
|
21883
22181
|
}
|
|
21884
22182
|
async function runVllmServer(args, verbose) {
|
|
21885
22183
|
return new Promise((resolve19, reject) => {
|
|
21886
|
-
const child =
|
|
22184
|
+
const child = spawn9("python", args, {
|
|
21887
22185
|
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
21888
22186
|
env: { ...process.env }
|
|
21889
22187
|
});
|
package/dist/launcher.cjs
CHANGED
|
@@ -198,10 +198,26 @@ if (nodeVersion < 18) {
|
|
|
198
198
|
}
|
|
199
199
|
console.log("");
|
|
200
200
|
console.log(" ┌─────────────────────────────────────────────────┐");
|
|
201
|
-
console.log(" │ Done!
|
|
201
|
+
console.log(" │ Done! Launching open-agents... │");
|
|
202
202
|
console.log(" └─────────────────────────────────────────────────┘");
|
|
203
203
|
console.log("");
|
|
204
204
|
rl.close();
|
|
205
|
+
|
|
206
|
+
// Auto-source shell config and re-exec oa — no "open a new terminal" needed
|
|
207
|
+
var rcFile = shell.indexOf("zsh") !== -1 ? "~/.zshrc" : "~/.bashrc";
|
|
208
|
+
var relaunchCmd = 'export NVM_DIR="' + nvmDir + '" && ' +
|
|
209
|
+
'[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && ' +
|
|
210
|
+
"source " + rcFile + " 2>/dev/null; " +
|
|
211
|
+
"exec oa";
|
|
212
|
+
try {
|
|
213
|
+
childProcess.execSync(shell + " -c '" + relaunchCmd + "'", {
|
|
214
|
+
stdio: "inherit",
|
|
215
|
+
env: process.env,
|
|
216
|
+
});
|
|
217
|
+
} catch (e) {
|
|
218
|
+
// Fallback: tell user to open new terminal only if re-exec fails
|
|
219
|
+
console.log("\n If oa didn't launch, run: source " + rcFile + " && oa\n");
|
|
220
|
+
}
|
|
205
221
|
process.exit(0);
|
|
206
222
|
});
|
|
207
223
|
}
|
package/package.json
CHANGED