@bunny-agent/runner-cli 0.9.32 → 0.9.34
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/bundle.mjs +124 -29
- package/package.json +3 -3
package/dist/bundle.mjs
CHANGED
|
@@ -1388,20 +1388,37 @@ var generateImageSchema = {
|
|
|
1388
1388
|
size: {
|
|
1389
1389
|
type: "string",
|
|
1390
1390
|
enum: [
|
|
1391
|
+
"auto",
|
|
1392
|
+
"1024x1024",
|
|
1393
|
+
"1536x1024",
|
|
1394
|
+
"1024x1536",
|
|
1391
1395
|
"256x256",
|
|
1392
1396
|
"512x512",
|
|
1393
|
-
"1024x1024",
|
|
1394
1397
|
"1792x1024",
|
|
1395
|
-
"1024x1792"
|
|
1396
|
-
"1280x1280",
|
|
1397
|
-
"1568x1056",
|
|
1398
|
-
"1056x1568",
|
|
1399
|
-
"1472x1088",
|
|
1400
|
-
"1088x1472",
|
|
1401
|
-
"1728x960",
|
|
1402
|
-
"960x1728"
|
|
1398
|
+
"1024x1792"
|
|
1403
1399
|
],
|
|
1404
|
-
description: "Image dimensions.
|
|
1400
|
+
description: "Image dimensions. Supported values: auto, 1024x1024, 1536x1024, 1024x1536, 256x256, 512x512, 1792x1024, 1024x1792."
|
|
1401
|
+
},
|
|
1402
|
+
aspectRatio: {
|
|
1403
|
+
type: "string",
|
|
1404
|
+
enum: [
|
|
1405
|
+
"1:1",
|
|
1406
|
+
"3:2",
|
|
1407
|
+
"2:3",
|
|
1408
|
+
"3:4",
|
|
1409
|
+
"4:3",
|
|
1410
|
+
"4:5",
|
|
1411
|
+
"5:4",
|
|
1412
|
+
"9:16",
|
|
1413
|
+
"16:9",
|
|
1414
|
+
"21:9"
|
|
1415
|
+
],
|
|
1416
|
+
description: "Image aspect ratio. Use this instead of size for models that support it when exact proportions matter. Supported values: 1:1, 3:2, 2:3, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9."
|
|
1417
|
+
},
|
|
1418
|
+
imageSize: {
|
|
1419
|
+
type: "string",
|
|
1420
|
+
enum: ["1K", "2K", "4K"],
|
|
1421
|
+
description: "Image resolution for models that support K-resolution output. Use this for requests like 2K or 4K."
|
|
1405
1422
|
},
|
|
1406
1423
|
quality: {
|
|
1407
1424
|
type: "string",
|
|
@@ -1412,6 +1429,33 @@ var generateImageSchema = {
|
|
|
1412
1429
|
required: ["prompt"],
|
|
1413
1430
|
additionalProperties: false
|
|
1414
1431
|
};
|
|
1432
|
+
var hasImagePayload = (item) => Boolean(item.b64_json ?? item.b64Json ?? item.image_base64 ?? item.imageBase64 ?? item.base64 ?? item.data ?? item.inlineData?.data ?? item.inline_data?.data ?? item.url ?? item.image_url ?? item.imageUrl ?? (typeof item.image === "string" ? item.image : item.image?.b64_json ?? item.image?.base64 ?? item.image?.data ?? item.image?.url));
|
|
1433
|
+
function readString(value) {
|
|
1434
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1435
|
+
}
|
|
1436
|
+
function readInlineData(value) {
|
|
1437
|
+
if (!value || typeof value !== "object")
|
|
1438
|
+
return void 0;
|
|
1439
|
+
const obj = value;
|
|
1440
|
+
return {
|
|
1441
|
+
data: readString(obj.data),
|
|
1442
|
+
mimeType: readString(obj.mimeType),
|
|
1443
|
+
mime_type: readString(obj.mime_type)
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
function readImage(value) {
|
|
1447
|
+
if (typeof value === "string" && value.length > 0)
|
|
1448
|
+
return value;
|
|
1449
|
+
if (!value || typeof value !== "object")
|
|
1450
|
+
return void 0;
|
|
1451
|
+
const obj = value;
|
|
1452
|
+
return {
|
|
1453
|
+
base64: readString(obj.base64),
|
|
1454
|
+
b64_json: readString(obj.b64_json),
|
|
1455
|
+
url: readString(obj.url),
|
|
1456
|
+
data: readString(obj.data)
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1415
1459
|
async function resolveB64(item, apiKey) {
|
|
1416
1460
|
if (item.b64_json)
|
|
1417
1461
|
return item.b64_json;
|
|
@@ -1423,12 +1467,20 @@ async function resolveB64(item, apiKey) {
|
|
|
1423
1467
|
return item.imageBase64;
|
|
1424
1468
|
if (item.base64)
|
|
1425
1469
|
return item.base64;
|
|
1470
|
+
if (item.data)
|
|
1471
|
+
return item.data;
|
|
1472
|
+
if (item.inlineData?.data)
|
|
1473
|
+
return item.inlineData.data;
|
|
1474
|
+
if (item.inline_data?.data)
|
|
1475
|
+
return item.inline_data.data;
|
|
1426
1476
|
if (typeof item.image === "string")
|
|
1427
1477
|
return item.image;
|
|
1428
1478
|
if (item.image?.b64_json)
|
|
1429
1479
|
return item.image.b64_json;
|
|
1430
1480
|
if (item.image?.base64)
|
|
1431
1481
|
return item.image.base64;
|
|
1482
|
+
if (item.image?.data)
|
|
1483
|
+
return item.image.data;
|
|
1432
1484
|
const url = item.url ?? item.image_url ?? item.imageUrl ?? item.image?.url;
|
|
1433
1485
|
if (url) {
|
|
1434
1486
|
const headers = {};
|
|
@@ -1446,16 +1498,24 @@ function pickImageItem(response) {
|
|
|
1446
1498
|
if (!value || typeof value !== "object")
|
|
1447
1499
|
return void 0;
|
|
1448
1500
|
const obj = value;
|
|
1501
|
+
const image = readImage(obj.image);
|
|
1502
|
+
const inlineData = readInlineData(obj.inlineData);
|
|
1503
|
+
const inline_data = readInlineData(obj.inline_data);
|
|
1449
1504
|
return {
|
|
1450
|
-
b64_json: obj.b64_json ?? obj.b64Json,
|
|
1451
|
-
b64Json: obj.b64Json,
|
|
1452
|
-
url: obj.url ?? obj.imageUrl,
|
|
1453
|
-
image_base64: obj.image_base64 ?? obj.imageBase64,
|
|
1454
|
-
imageBase64: obj.imageBase64,
|
|
1455
|
-
image_url: obj.image_url ?? obj.imageUrl,
|
|
1456
|
-
imageUrl: obj.imageUrl,
|
|
1457
|
-
base64: obj.base64,
|
|
1458
|
-
|
|
1505
|
+
b64_json: readString(obj.b64_json) ?? readString(obj.b64Json),
|
|
1506
|
+
b64Json: readString(obj.b64Json),
|
|
1507
|
+
url: readString(obj.url) ?? readString(obj.imageUrl),
|
|
1508
|
+
image_base64: readString(obj.image_base64) ?? readString(obj.imageBase64),
|
|
1509
|
+
imageBase64: readString(obj.imageBase64),
|
|
1510
|
+
image_url: readString(obj.image_url) ?? readString(obj.imageUrl),
|
|
1511
|
+
imageUrl: readString(obj.imageUrl),
|
|
1512
|
+
base64: readString(obj.base64),
|
|
1513
|
+
data: readString(obj.data),
|
|
1514
|
+
mimeType: readString(obj.mimeType),
|
|
1515
|
+
mime_type: readString(obj.mime_type),
|
|
1516
|
+
inlineData,
|
|
1517
|
+
inline_data,
|
|
1518
|
+
image
|
|
1459
1519
|
};
|
|
1460
1520
|
};
|
|
1461
1521
|
const asItem = (value) => {
|
|
@@ -1466,7 +1526,7 @@ function pickImageItem(response) {
|
|
|
1466
1526
|
}
|
|
1467
1527
|
if (typeof value === "object") {
|
|
1468
1528
|
const normalized = tryFromObject(value);
|
|
1469
|
-
if (normalized)
|
|
1529
|
+
if (normalized && hasImagePayload(normalized))
|
|
1470
1530
|
return normalized;
|
|
1471
1531
|
}
|
|
1472
1532
|
return void 0;
|
|
@@ -1509,8 +1569,7 @@ function pickImageItem(response) {
|
|
|
1509
1569
|
continue;
|
|
1510
1570
|
const normalized = tryFromObject(current);
|
|
1511
1571
|
if (normalized) {
|
|
1512
|
-
|
|
1513
|
-
if (hasUsefulField)
|
|
1572
|
+
if (hasImagePayload(normalized))
|
|
1514
1573
|
return normalized;
|
|
1515
1574
|
}
|
|
1516
1575
|
if (Array.isArray(current)) {
|
|
@@ -1556,19 +1615,23 @@ function buildImageGenerateTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1556
1615
|
name: "generate_image",
|
|
1557
1616
|
label: "generate image",
|
|
1558
1617
|
description: "Generate an image from a text prompt. Saves the image to disk and returns the file path.",
|
|
1559
|
-
promptSnippet: "generate_image(prompt, filename?, size?, quality?) - generate an image from text",
|
|
1618
|
+
promptSnippet: "generate_image(prompt, filename?, size?, aspectRatio?, imageSize?, quality?) - generate an image from text",
|
|
1560
1619
|
promptGuidelines: [
|
|
1561
1620
|
"Use generate_image when the user asks to create, draw, or visualize something.",
|
|
1562
1621
|
"Be descriptive in the prompt \u2014 more detail produces better results.",
|
|
1563
|
-
"Provide a filename with extension, e.g. 'cat.png'."
|
|
1622
|
+
"Provide a filename with extension, e.g. 'cat.png'.",
|
|
1623
|
+
"Use aspectRatio (e.g. '3:4') when the requested output needs specific proportions.",
|
|
1624
|
+
"Use imageSize (e.g. '2K') when the user requests 1K, 2K, or 4K resolution."
|
|
1564
1625
|
],
|
|
1565
1626
|
// biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
|
|
1566
1627
|
parameters: generateImageSchema,
|
|
1567
1628
|
async execute(_toolCallId, params, signal, _onUpdate) {
|
|
1568
1629
|
const p = params;
|
|
1569
1630
|
const prompt = p.prompt;
|
|
1570
|
-
const size = p.size
|
|
1631
|
+
const size = p.size;
|
|
1571
1632
|
const quality = p.quality ?? "auto";
|
|
1633
|
+
const aspectRatio = p.aspectRatio;
|
|
1634
|
+
const imageSize = p.imageSize;
|
|
1572
1635
|
const rawFilename = p.filename;
|
|
1573
1636
|
const filename = rawFilename ? extname(rawFilename) ? rawFilename : `${rawFilename}.png` : `image_${Date.now()}.png`;
|
|
1574
1637
|
const filePath = join6(cwd, filename.replace(/[^a-zA-Z0-9_\-./]/g, "_"));
|
|
@@ -1584,10 +1647,12 @@ function buildImageGenerateTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1584
1647
|
model: imageModelId,
|
|
1585
1648
|
prompt,
|
|
1586
1649
|
n: 1,
|
|
1587
|
-
size,
|
|
1588
1650
|
quality,
|
|
1589
1651
|
response_format: "b64_json",
|
|
1590
|
-
output_format: "png"
|
|
1652
|
+
output_format: "png",
|
|
1653
|
+
...aspectRatio ? { aspect_ratio: aspectRatio } : {},
|
|
1654
|
+
...imageSize ? { image_size: imageSize } : {},
|
|
1655
|
+
...size ? { size } : !aspectRatio && !imageSize ? { size: "1024x1024" } : {}
|
|
1591
1656
|
}),
|
|
1592
1657
|
signal
|
|
1593
1658
|
});
|
|
@@ -1649,6 +1714,27 @@ var editImageSchema = {
|
|
|
1649
1714
|
type: "string",
|
|
1650
1715
|
enum: ["low", "medium", "high", "auto"],
|
|
1651
1716
|
description: "Image quality. Optional; omit or set auto to let model decide."
|
|
1717
|
+
},
|
|
1718
|
+
aspectRatio: {
|
|
1719
|
+
type: "string",
|
|
1720
|
+
enum: [
|
|
1721
|
+
"1:1",
|
|
1722
|
+
"3:2",
|
|
1723
|
+
"2:3",
|
|
1724
|
+
"3:4",
|
|
1725
|
+
"4:3",
|
|
1726
|
+
"4:5",
|
|
1727
|
+
"5:4",
|
|
1728
|
+
"9:16",
|
|
1729
|
+
"16:9",
|
|
1730
|
+
"21:9"
|
|
1731
|
+
],
|
|
1732
|
+
description: "Gemini image aspect ratio. Use this instead of size for Gemini image edit models when exact proportions matter."
|
|
1733
|
+
},
|
|
1734
|
+
imageSize: {
|
|
1735
|
+
type: "string",
|
|
1736
|
+
enum: ["1K", "2K", "4K"],
|
|
1737
|
+
description: "Gemini output resolution for image edit models that support K-resolution output."
|
|
1652
1738
|
}
|
|
1653
1739
|
},
|
|
1654
1740
|
required: ["image", "prompt"],
|
|
@@ -1685,12 +1771,13 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1685
1771
|
name: "edit_image",
|
|
1686
1772
|
label: "edit image",
|
|
1687
1773
|
description: "Edit an existing image based on a text prompt. Optionally use a mask to control which areas to modify. Saves the result to disk and returns the file path.",
|
|
1688
|
-
promptSnippet: "edit_image(image, prompt, mask?, filename?, size?, quality?) - edit an existing image",
|
|
1774
|
+
promptSnippet: "edit_image(image, prompt, mask?, filename?, size?, quality?, aspectRatio?, imageSize?) - edit an existing image",
|
|
1689
1775
|
promptGuidelines: [
|
|
1690
1776
|
"Use edit_image when the user wants to modify, retouch, or transform an existing image.",
|
|
1691
1777
|
"The prompt should describe the full desired final image, not just the change.",
|
|
1692
1778
|
"Provide the source image path. Use a mask image (PNG with transparent areas) to control where edits happen.",
|
|
1693
|
-
"Without a mask, the model decides what to change based on the prompt."
|
|
1779
|
+
"Without a mask, the model decides what to change based on the prompt.",
|
|
1780
|
+
"For Gemini image edit models, use aspectRatio and imageSize when the user asks for those controls."
|
|
1694
1781
|
],
|
|
1695
1782
|
// biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
|
|
1696
1783
|
parameters: editImageSchema,
|
|
@@ -1703,6 +1790,8 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1703
1790
|
const maskPath = p.mask;
|
|
1704
1791
|
const size = p.size;
|
|
1705
1792
|
const quality = p.quality;
|
|
1793
|
+
const aspectRatio = p.aspectRatio;
|
|
1794
|
+
const imageSize = p.imageSize;
|
|
1706
1795
|
const rawFilename = p.filename;
|
|
1707
1796
|
const safePrompt = buildPolicySafeEditPrompt(prompt);
|
|
1708
1797
|
const resolvedImage = resolve4(cwd, imagePath);
|
|
@@ -1734,6 +1823,12 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
|
|
|
1734
1823
|
if (quality && quality !== "auto") {
|
|
1735
1824
|
fields.push({ name: "quality", value: quality });
|
|
1736
1825
|
}
|
|
1826
|
+
if (aspectRatio) {
|
|
1827
|
+
fields.push({ name: "aspect_ratio", value: aspectRatio });
|
|
1828
|
+
}
|
|
1829
|
+
if (imageSize) {
|
|
1830
|
+
fields.push({ name: "image_size", value: imageSize });
|
|
1831
|
+
}
|
|
1737
1832
|
const files = [
|
|
1738
1833
|
{
|
|
1739
1834
|
name: "image",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunny-agent/runner-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.34",
|
|
4
4
|
"description": "BunnyAgent Runner CLI - Like gemini-cli or claude-code, runs in your local terminal with AI SDK UI streaming",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"vitest": "^1.6.1",
|
|
56
56
|
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
57
57
|
"@bunny-agent/runner-opencode": "0.6.2",
|
|
58
|
-
"@bunny-agent/runner-
|
|
58
|
+
"@bunny-agent/runner-pi": "0.6.4-beta.0",
|
|
59
59
|
"@bunny-agent/runner-codex": "0.6.2",
|
|
60
60
|
"@bunny-agent/runner-claude": "0.6.2",
|
|
61
|
-
"@bunny-agent/runner-
|
|
61
|
+
"@bunny-agent/runner-gemini": "0.6.2"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "tsc && pnpm bundle",
|