open-agents-ai 0.15.2 → 0.15.4
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 +198 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8870,13 +8870,6 @@ ${newerSummary}` : newerSummary;
|
|
|
8870
8870
|
acc.id = chunk.toolCallId;
|
|
8871
8871
|
if (chunk.toolCallArgs) {
|
|
8872
8872
|
acc.args += chunk.toolCallArgs;
|
|
8873
|
-
this.emit({
|
|
8874
|
-
type: "stream_token",
|
|
8875
|
-
content: chunk.toolCallArgs,
|
|
8876
|
-
streamKind: "tool_args",
|
|
8877
|
-
turn,
|
|
8878
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
8879
|
-
});
|
|
8880
8873
|
}
|
|
8881
8874
|
}
|
|
8882
8875
|
}
|
|
@@ -9660,23 +9653,137 @@ function renderToolCallStart(toolName, args) {
|
|
|
9660
9653
|
`);
|
|
9661
9654
|
}
|
|
9662
9655
|
function renderToolResult(toolName, success, output) {
|
|
9663
|
-
const
|
|
9664
|
-
const
|
|
9656
|
+
const maxW = getTermWidth() - 10;
|
|
9657
|
+
const prefix = ` ${c2.dim("\u23BF")} `;
|
|
9658
|
+
switch (toolName) {
|
|
9659
|
+
case "file_write": {
|
|
9660
|
+
const summary = extractFirstLine(output, maxW);
|
|
9661
|
+
if (success) {
|
|
9662
|
+
process.stdout.write(`${prefix}${c2.dim(summary)}
|
|
9663
|
+
`);
|
|
9664
|
+
} else {
|
|
9665
|
+
process.stdout.write(`${prefix}${c2.red(summary)}
|
|
9666
|
+
`);
|
|
9667
|
+
}
|
|
9668
|
+
return;
|
|
9669
|
+
}
|
|
9670
|
+
case "file_edit": {
|
|
9671
|
+
const summary = extractFirstLine(output, maxW);
|
|
9672
|
+
if (success) {
|
|
9673
|
+
process.stdout.write(`${prefix}${c2.dim(summary)}
|
|
9674
|
+
`);
|
|
9675
|
+
} else {
|
|
9676
|
+
process.stdout.write(`${prefix}${c2.red(summary)}
|
|
9677
|
+
`);
|
|
9678
|
+
}
|
|
9679
|
+
return;
|
|
9680
|
+
}
|
|
9681
|
+
case "file_read": {
|
|
9682
|
+
if (!success) {
|
|
9683
|
+
process.stdout.write(`${prefix}${c2.red(extractFirstLine(output, maxW))}
|
|
9684
|
+
`);
|
|
9685
|
+
return;
|
|
9686
|
+
}
|
|
9687
|
+
renderCodePreview(output, prefix, maxW, 6);
|
|
9688
|
+
return;
|
|
9689
|
+
}
|
|
9690
|
+
case "shell":
|
|
9691
|
+
case "background_run": {
|
|
9692
|
+
renderShellOutput(output, success, prefix, maxW, 8);
|
|
9693
|
+
return;
|
|
9694
|
+
}
|
|
9695
|
+
case "grep_search": {
|
|
9696
|
+
renderShellOutput(output, success, prefix, maxW, 6);
|
|
9697
|
+
return;
|
|
9698
|
+
}
|
|
9699
|
+
case "task_complete": {
|
|
9700
|
+
process.stdout.write(`${prefix}${c2.green("\u2714")} ${c2.dim("Done")}
|
|
9701
|
+
`);
|
|
9702
|
+
return;
|
|
9703
|
+
}
|
|
9704
|
+
default:
|
|
9705
|
+
break;
|
|
9706
|
+
}
|
|
9665
9707
|
const lines = output.split("\n").filter((l) => l.trim());
|
|
9666
9708
|
if (lines.length === 0) {
|
|
9667
|
-
|
|
9709
|
+
const icon = success ? _emojisEnabled ? c2.green("\u2714") : c2.green("+") : _emojisEnabled ? c2.red("\u2716") : c2.red("x");
|
|
9710
|
+
process.stdout.write(`${prefix}${icon} ${success ? c2.dim("Done") : c2.red("Failed")}
|
|
9668
9711
|
`);
|
|
9669
9712
|
return;
|
|
9670
9713
|
}
|
|
9714
|
+
const maxLines = 6;
|
|
9671
9715
|
const shown = lines.slice(0, maxLines);
|
|
9672
9716
|
for (const line of shown) {
|
|
9673
|
-
|
|
9717
|
+
if (isRawJsonDump(line)) {
|
|
9718
|
+
process.stdout.write(`${prefix}${c2.dim("(content omitted)")}
|
|
9719
|
+
`);
|
|
9720
|
+
return;
|
|
9721
|
+
}
|
|
9674
9722
|
const trimmed = line.length > maxW ? line.slice(0, maxW - 3) + "..." : line;
|
|
9675
|
-
process.stdout.write(
|
|
9723
|
+
process.stdout.write(`${prefix}${highlightToolOutput(trimmed)}
|
|
9724
|
+
`);
|
|
9725
|
+
}
|
|
9726
|
+
if (lines.length > maxLines) {
|
|
9727
|
+
process.stdout.write(`${prefix}${c2.dim(`... ${lines.length - maxLines} more lines`)}
|
|
9728
|
+
`);
|
|
9729
|
+
}
|
|
9730
|
+
}
|
|
9731
|
+
function extractFirstLine(output, maxW) {
|
|
9732
|
+
const line = output.split("\n").find((l) => l.trim()) ?? output;
|
|
9733
|
+
return line.length > maxW ? line.slice(0, maxW - 3) + "..." : line;
|
|
9734
|
+
}
|
|
9735
|
+
function isRawJsonDump(line) {
|
|
9736
|
+
if (/\\u[0-9a-fA-F]{4}/.test(line) && line.length > 200)
|
|
9737
|
+
return true;
|
|
9738
|
+
if (/^\s*\{"content"\s*:/.test(line) && line.length > 100)
|
|
9739
|
+
return true;
|
|
9740
|
+
if (/\[38;5;\d+m/.test(line) && line.length > 100)
|
|
9741
|
+
return true;
|
|
9742
|
+
return false;
|
|
9743
|
+
}
|
|
9744
|
+
function renderCodePreview(output, prefix, maxW, maxLines) {
|
|
9745
|
+
const lines = output.split("\n");
|
|
9746
|
+
let start = 0;
|
|
9747
|
+
while (start < lines.length && !lines[start].trim())
|
|
9748
|
+
start++;
|
|
9749
|
+
const shown = lines.slice(start, start + maxLines);
|
|
9750
|
+
if (shown.length === 0) {
|
|
9751
|
+
process.stdout.write(`${prefix}${c2.dim("(empty file)")}
|
|
9752
|
+
`);
|
|
9753
|
+
return;
|
|
9754
|
+
}
|
|
9755
|
+
for (const line of shown) {
|
|
9756
|
+
const cropped = line.length > maxW ? line.slice(0, maxW - 3) + "..." : line;
|
|
9757
|
+
process.stdout.write(`${prefix}${c2.dim(cropped)}
|
|
9758
|
+
`);
|
|
9759
|
+
}
|
|
9760
|
+
const remaining = lines.length - start - shown.length;
|
|
9761
|
+
if (remaining > 0) {
|
|
9762
|
+
process.stdout.write(`${prefix}${c2.dim(`... ${remaining} more lines`)}
|
|
9763
|
+
`);
|
|
9764
|
+
}
|
|
9765
|
+
}
|
|
9766
|
+
function renderShellOutput(output, success, prefix, maxW, maxLines) {
|
|
9767
|
+
const lines = output.split("\n").filter((l) => l.trim());
|
|
9768
|
+
if (lines.length === 0) {
|
|
9769
|
+
const icon = success ? c2.green("\u2714") : c2.red("\u2716");
|
|
9770
|
+
process.stdout.write(`${prefix}${icon} ${success ? c2.dim("Done") : c2.red("Failed")}
|
|
9771
|
+
`);
|
|
9772
|
+
return;
|
|
9773
|
+
}
|
|
9774
|
+
const shown = lines.slice(0, maxLines);
|
|
9775
|
+
for (const line of shown) {
|
|
9776
|
+
if (isRawJsonDump(line)) {
|
|
9777
|
+
process.stdout.write(`${prefix}${c2.dim("(output omitted)")}
|
|
9778
|
+
`);
|
|
9779
|
+
return;
|
|
9780
|
+
}
|
|
9781
|
+
const cropped = line.length > maxW ? line.slice(0, maxW - 3) + "..." : line;
|
|
9782
|
+
process.stdout.write(`${prefix}${highlightToolOutput(cropped)}
|
|
9676
9783
|
`);
|
|
9677
9784
|
}
|
|
9678
9785
|
if (lines.length > maxLines) {
|
|
9679
|
-
process.stdout.write(
|
|
9786
|
+
process.stdout.write(`${prefix}${c2.dim(`... ${lines.length - maxLines} more lines`)}
|
|
9680
9787
|
`);
|
|
9681
9788
|
}
|
|
9682
9789
|
}
|
|
@@ -11084,7 +11191,7 @@ async function handleSlashCommand(input, ctx) {
|
|
|
11084
11191
|
return "handled";
|
|
11085
11192
|
case "update":
|
|
11086
11193
|
case "upgrade":
|
|
11087
|
-
await handleUpdate(arg, ctx
|
|
11194
|
+
await handleUpdate(arg, ctx);
|
|
11088
11195
|
return "handled";
|
|
11089
11196
|
case "voice": {
|
|
11090
11197
|
const save = hasLocal ? ctx.saveLocalSettings.bind(ctx) : ctx.saveSettings.bind(ctx);
|
|
@@ -11374,7 +11481,8 @@ async function handleEndpoint(arg, ctx, local = false) {
|
|
|
11374
11481
|
}
|
|
11375
11482
|
process.stdout.write("\n");
|
|
11376
11483
|
}
|
|
11377
|
-
async function handleUpdate(subcommand,
|
|
11484
|
+
async function handleUpdate(subcommand, ctx) {
|
|
11485
|
+
const repoRoot = ctx.repoRoot;
|
|
11378
11486
|
if (subcommand === "auto") {
|
|
11379
11487
|
const settings = { updateMode: "auto" };
|
|
11380
11488
|
saveProjectSettings(repoRoot, settings);
|
|
@@ -11425,17 +11533,33 @@ async function handleUpdate(subcommand, repoRoot) {
|
|
|
11425
11533
|
}
|
|
11426
11534
|
process.stdout.write(` ${c2.yellow("\u26A0")} Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}
|
|
11427
11535
|
`);
|
|
11428
|
-
process.stdout.write(` ${c2.cyan("\u25CF")} Installing
|
|
11536
|
+
process.stdout.write(` ${c2.cyan("\u25CF")} Installing update...
|
|
11429
11537
|
|
|
11430
11538
|
`);
|
|
11431
|
-
const {
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11438
|
-
}
|
|
11539
|
+
const { execSync: execSync14 } = await import("node:child_process");
|
|
11540
|
+
try {
|
|
11541
|
+
execSync14(`npm cache clean --force open-agents-ai 2>/dev/null; npm install -g open-agents-ai@latest --force`, { stdio: "pipe", timeout: 18e4 });
|
|
11542
|
+
} catch {
|
|
11543
|
+
renderWarning("Update install failed. Try manually: npm i -g open-agents-ai");
|
|
11544
|
+
return;
|
|
11545
|
+
}
|
|
11546
|
+
process.stdout.write(` ${c2.green("\u2714")} Installed v${info.latestVersion}. Reloading...
|
|
11547
|
+
|
|
11548
|
+
`);
|
|
11549
|
+
if (ctx.savePendingTaskState) {
|
|
11550
|
+
ctx.savePendingTaskState();
|
|
11551
|
+
}
|
|
11552
|
+
const { execPath, argv } = process;
|
|
11553
|
+
try {
|
|
11554
|
+
const { execFileSync } = await import("node:child_process");
|
|
11555
|
+
process.env.__OA_RESUMED = "1";
|
|
11556
|
+
execFileSync(execPath, argv.slice(1), {
|
|
11557
|
+
stdio: "inherit",
|
|
11558
|
+
env: { ...process.env, __OA_RESUMED: "1" }
|
|
11559
|
+
});
|
|
11560
|
+
} catch {
|
|
11561
|
+
renderWarning("Reload failed. Restart oa manually to use the new version.");
|
|
11562
|
+
}
|
|
11439
11563
|
}
|
|
11440
11564
|
async function switchModel(query, ctx, local = false) {
|
|
11441
11565
|
try {
|
|
@@ -13253,6 +13377,12 @@ var init_stream_renderer = __esm({
|
|
|
13253
13377
|
startTime = 0;
|
|
13254
13378
|
/** Track if we're mid-tool-arg display */
|
|
13255
13379
|
inToolArgs = false;
|
|
13380
|
+
/**
|
|
13381
|
+
* Track accumulated content size for JSON blob detection.
|
|
13382
|
+
* When a non-newline JSON blob exceeds this threshold, suppress rendering.
|
|
13383
|
+
*/
|
|
13384
|
+
jsonBlobSize = 0;
|
|
13385
|
+
jsonBlobSuppressed = false;
|
|
13256
13386
|
/** Called when a new model response starts streaming */
|
|
13257
13387
|
onStreamStart() {
|
|
13258
13388
|
this.lineBuffer = "";
|
|
@@ -13261,6 +13391,8 @@ var init_stream_renderer = __esm({
|
|
|
13261
13391
|
this.codeLang = "";
|
|
13262
13392
|
this.lineStarted = false;
|
|
13263
13393
|
this.inToolArgs = false;
|
|
13394
|
+
this.jsonBlobSize = 0;
|
|
13395
|
+
this.jsonBlobSuppressed = false;
|
|
13264
13396
|
this.enabled = true;
|
|
13265
13397
|
this.tokenCount = 0;
|
|
13266
13398
|
this.startTime = Date.now();
|
|
@@ -13371,8 +13503,26 @@ var init_stream_renderer = __esm({
|
|
|
13371
13503
|
const raw = text.replace(/\n$/, "");
|
|
13372
13504
|
if (!raw)
|
|
13373
13505
|
return;
|
|
13374
|
-
const prefix = this.lineStarted ? "" : " \u23BF ";
|
|
13375
13506
|
const hasNewline = text.endsWith("\n");
|
|
13507
|
+
if (kind === "tool_args" || kind === "content" && this.looksLikeJsonBlob(raw)) {
|
|
13508
|
+
this.jsonBlobSize += raw.length;
|
|
13509
|
+
if (this.jsonBlobSize > 300) {
|
|
13510
|
+
if (!this.jsonBlobSuppressed) {
|
|
13511
|
+
this.jsonBlobSuppressed = true;
|
|
13512
|
+
}
|
|
13513
|
+
if (hasNewline) {
|
|
13514
|
+
this.jsonBlobSize = 0;
|
|
13515
|
+
this.jsonBlobSuppressed = false;
|
|
13516
|
+
}
|
|
13517
|
+
return;
|
|
13518
|
+
}
|
|
13519
|
+
} else {
|
|
13520
|
+
if (this.jsonBlobSuppressed || this.jsonBlobSize > 0) {
|
|
13521
|
+
this.jsonBlobSize = 0;
|
|
13522
|
+
this.jsonBlobSuppressed = false;
|
|
13523
|
+
}
|
|
13524
|
+
}
|
|
13525
|
+
const prefix = this.lineStarted ? "" : " \u23BF ";
|
|
13376
13526
|
let rendered;
|
|
13377
13527
|
switch (kind) {
|
|
13378
13528
|
case "thinking":
|
|
@@ -13381,19 +13531,21 @@ var init_stream_renderer = __esm({
|
|
|
13381
13531
|
case "tool_args":
|
|
13382
13532
|
rendered = this.highlightJson(raw, true);
|
|
13383
13533
|
break;
|
|
13384
|
-
case "content":
|
|
13534
|
+
case "content": {
|
|
13535
|
+
const maxW = (process.stdout.columns ?? 80) - 6;
|
|
13385
13536
|
if (this.inCodeBlock) {
|
|
13537
|
+
const cropped = raw.length > maxW ? raw.slice(0, maxW - 3) + "..." : raw;
|
|
13386
13538
|
if (this.codeLang === "diff" || this.codeLang === "patch") {
|
|
13387
|
-
rendered = this.highlightDiff(
|
|
13539
|
+
rendered = this.highlightDiff(cropped);
|
|
13388
13540
|
} else if (this.codeLang === "bash" || this.codeLang === "sh" || this.codeLang === "shell" || this.codeLang === "zsh") {
|
|
13389
|
-
rendered = this.highlightShell(
|
|
13541
|
+
rendered = this.highlightShell(cropped);
|
|
13390
13542
|
} else {
|
|
13391
|
-
rendered = this.highlightCode(
|
|
13543
|
+
rendered = this.highlightCode(cropped);
|
|
13392
13544
|
}
|
|
13393
13545
|
} else if (this.looksLikeJson(raw)) {
|
|
13394
|
-
|
|
13546
|
+
const cropped = raw.length > maxW ? raw.slice(0, maxW - 3) + "..." : raw;
|
|
13547
|
+
rendered = this.highlightJson(cropped, false);
|
|
13395
13548
|
} else {
|
|
13396
|
-
const maxW = (process.stdout.columns ?? 80) - 6;
|
|
13397
13549
|
if (raw.length > maxW) {
|
|
13398
13550
|
const wrapped = this.wordWrap(raw, maxW);
|
|
13399
13551
|
for (let i = 0; i < wrapped.length; i++) {
|
|
@@ -13407,6 +13559,7 @@ var init_stream_renderer = __esm({
|
|
|
13407
13559
|
rendered = this.highlightMarkdown(raw);
|
|
13408
13560
|
}
|
|
13409
13561
|
break;
|
|
13562
|
+
}
|
|
13410
13563
|
}
|
|
13411
13564
|
this.writeRaw(dimText(prefix) + rendered + (hasNewline ? "\n" : ""));
|
|
13412
13565
|
this.lineStarted = !hasNewline;
|
|
@@ -13446,6 +13599,20 @@ var init_stream_renderer = __esm({
|
|
|
13446
13599
|
const trimmed = text.trimStart();
|
|
13447
13600
|
return trimmed.startsWith("{") || trimmed.startsWith("[") || trimmed.startsWith("}") || trimmed.startsWith("]") || /^\s*"[^"]+"\s*:/.test(trimmed);
|
|
13448
13601
|
}
|
|
13602
|
+
/**
|
|
13603
|
+
* Detect a JSON blob that likely contains serialized file content.
|
|
13604
|
+
* These are tool call args that leaked into the content stream —
|
|
13605
|
+
* they contain escaped unicode (\u003e), literal \n, or "content": keys.
|
|
13606
|
+
*/
|
|
13607
|
+
looksLikeJsonBlob(text) {
|
|
13608
|
+
if (/\\u[0-9a-fA-F]{4}/.test(text))
|
|
13609
|
+
return true;
|
|
13610
|
+
if (/^\s*\{?"content"\s*:/.test(text))
|
|
13611
|
+
return true;
|
|
13612
|
+
if (text.includes("\\n") && this.looksLikeJson(text) && text.length > 100)
|
|
13613
|
+
return true;
|
|
13614
|
+
return false;
|
|
13615
|
+
}
|
|
13449
13616
|
/**
|
|
13450
13617
|
* Highlight a JSON line with pastel colors.
|
|
13451
13618
|
* @param dim If true, apply dimmer colors (for tool args)
|
package/package.json
CHANGED