open-agents-ai 0.184.79 → 0.184.81
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 +76 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16206,7 +16206,7 @@ var init_desktop_click = __esm({
|
|
|
16206
16206
|
DesktopClickTool = class {
|
|
16207
16207
|
workingDir;
|
|
16208
16208
|
name = "desktop_click";
|
|
16209
|
-
description = "Click on a UI element identified by natural language description. Takes a screenshot, uses vision to find the
|
|
16209
|
+
description = "Click on a UI element identified by natural language description. Takes a screenshot, uses Moondream vision to find the element's coordinates, then clicks at that location. Supports single click, double click, and right click.\n Single click: desktop_click({ target: 'the Save button' })\n Double click: desktop_click({ target: 'document.pdf', click_type: 'double' })\n Right click: desktop_click({ target: 'file icon', button: 'right' })\nChain multiple calls for complex interactions (e.g. right-click \u2192 select menu item).";
|
|
16210
16210
|
/** Active Ollama model name — used as vision fallback if it has vision capability */
|
|
16211
16211
|
_activeModel = "";
|
|
16212
16212
|
/** Whether the active model has vision capability */
|
|
@@ -16303,20 +16303,51 @@ var init_desktop_click = __esm({
|
|
|
16303
16303
|
const envModel = process.env["OLLAMA_VISION_MODEL"];
|
|
16304
16304
|
const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
|
|
16305
16305
|
const imageBase64 = readFileSync15(screenshotPath).toString("base64");
|
|
16306
|
-
|
|
16306
|
+
let res = await fetch(`${ollamaHost}/api/generate`, {
|
|
16307
16307
|
method: "POST",
|
|
16308
16308
|
headers: { "Content-Type": "application/json" },
|
|
16309
|
-
body: JSON.stringify({ model: ollamaModel, prompt: `
|
|
16309
|
+
body: JSON.stringify({ model: ollamaModel, prompt: `Locate the "${target}" in this image and give its x,y position as normalized coordinates.`, images: [imageBase64], stream: false }),
|
|
16310
16310
|
signal: AbortSignal.timeout(6e4)
|
|
16311
16311
|
});
|
|
16312
|
+
if (!res.ok && ollamaModel === "moondream") {
|
|
16313
|
+
const errText = await res.text().catch(() => "");
|
|
16314
|
+
if (res.status === 404 || /not found|does not exist/i.test(errText)) {
|
|
16315
|
+
try {
|
|
16316
|
+
const { execSync: es } = await import("node:child_process");
|
|
16317
|
+
es("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
16318
|
+
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
16319
|
+
method: "POST",
|
|
16320
|
+
headers: { "Content-Type": "application/json" },
|
|
16321
|
+
body: JSON.stringify({ model: ollamaModel, prompt: `Locate the "${target}" in this image and give its x,y position as normalized coordinates.`, images: [imageBase64], stream: false }),
|
|
16322
|
+
signal: AbortSignal.timeout(6e4)
|
|
16323
|
+
});
|
|
16324
|
+
} catch {
|
|
16325
|
+
}
|
|
16326
|
+
}
|
|
16327
|
+
}
|
|
16312
16328
|
if (res.ok) {
|
|
16313
16329
|
const data = await res.json();
|
|
16314
16330
|
const response = data.response || "";
|
|
16315
|
-
const
|
|
16316
|
-
if (
|
|
16317
|
-
points =
|
|
16331
|
+
const xmlMatches = [...response.matchAll(/<point\s+x="([\d.]+)"\s+y="([\d.]+)"\s*\/?>/g)];
|
|
16332
|
+
if (xmlMatches.length > 0) {
|
|
16333
|
+
points = xmlMatches.map((m) => ({ x: parseFloat(m[1]), y: parseFloat(m[2]) }));
|
|
16318
16334
|
visionWorked = true;
|
|
16319
16335
|
}
|
|
16336
|
+
if (!visionWorked) {
|
|
16337
|
+
const arrayMatch = response.match(/\[\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+)\s*,\s*([\d.]+))?\s*\]/);
|
|
16338
|
+
if (arrayMatch) {
|
|
16339
|
+
const x1 = parseFloat(arrayMatch[1]);
|
|
16340
|
+
const y1 = parseFloat(arrayMatch[2]);
|
|
16341
|
+
if (arrayMatch[3] && arrayMatch[4]) {
|
|
16342
|
+
const x2 = parseFloat(arrayMatch[3]);
|
|
16343
|
+
const y2 = parseFloat(arrayMatch[4]);
|
|
16344
|
+
points = [{ x: (x1 + x2) / 2, y: (y1 + y2) / 2 }];
|
|
16345
|
+
} else {
|
|
16346
|
+
points = [{ x: x1, y: y1 }];
|
|
16347
|
+
}
|
|
16348
|
+
visionWorked = true;
|
|
16349
|
+
}
|
|
16350
|
+
}
|
|
16320
16351
|
}
|
|
16321
16352
|
} catch {
|
|
16322
16353
|
}
|
|
@@ -16480,12 +16511,28 @@ ${caption}`);
|
|
|
16480
16511
|
const ollamaModel = envModel || (this._activeModelHasVision && this._activeModel ? this._activeModel : "moondream");
|
|
16481
16512
|
const imageBase64 = imageBuffer.toString("base64");
|
|
16482
16513
|
const ollamaPrompt = question || "Describe what you see on this desktop screenshot in detail. Include visible applications, windows, text, and UI elements.";
|
|
16483
|
-
|
|
16514
|
+
let res = await fetch(`${ollamaHost}/api/generate`, {
|
|
16484
16515
|
method: "POST",
|
|
16485
16516
|
headers: { "Content-Type": "application/json" },
|
|
16486
16517
|
body: JSON.stringify({ model: ollamaModel, prompt: ollamaPrompt, images: [imageBase64], stream: false }),
|
|
16487
16518
|
signal: AbortSignal.timeout(6e4)
|
|
16488
16519
|
});
|
|
16520
|
+
if (!res.ok && ollamaModel === "moondream") {
|
|
16521
|
+
const errText = await res.text().catch(() => "");
|
|
16522
|
+
if (res.status === 404 || /not found|does not exist/i.test(errText)) {
|
|
16523
|
+
try {
|
|
16524
|
+
const { execSync: es } = await import("node:child_process");
|
|
16525
|
+
es("ollama pull moondream", { timeout: 3e5, stdio: "pipe" });
|
|
16526
|
+
res = await fetch(`${ollamaHost}/api/generate`, {
|
|
16527
|
+
method: "POST",
|
|
16528
|
+
headers: { "Content-Type": "application/json" },
|
|
16529
|
+
body: JSON.stringify({ model: ollamaModel, prompt: ollamaPrompt, images: [imageBase64], stream: false }),
|
|
16530
|
+
signal: AbortSignal.timeout(6e4)
|
|
16531
|
+
});
|
|
16532
|
+
} catch {
|
|
16533
|
+
}
|
|
16534
|
+
}
|
|
16535
|
+
}
|
|
16489
16536
|
if (res.ok) {
|
|
16490
16537
|
const data = await res.json();
|
|
16491
16538
|
if (data.response) {
|
|
@@ -64433,26 +64480,28 @@ ${lines.join("\n")}
|
|
|
64433
64480
|
dynamicContext += `
|
|
64434
64481
|
|
|
64435
64482
|
<vision-capabilities>
|
|
64436
|
-
You have vision capabilities available.
|
|
64437
|
-
|
|
64438
|
-
|
|
64439
|
-
|
|
64440
|
-
|
|
64441
|
-
|
|
64442
|
-
|
|
64443
|
-
|
|
64444
|
-
|
|
64445
|
-
|
|
64446
|
-
|
|
64447
|
-
|
|
64448
|
-
|
|
64449
|
-
|
|
64450
|
-
|
|
64451
|
-
|
|
64452
|
-
|
|
64453
|
-
|
|
64454
|
-
|
|
64455
|
-
|
|
64483
|
+
You have vision capabilities available.
|
|
64484
|
+
|
|
64485
|
+
IMAGE ANALYSIS:
|
|
64486
|
+
image_read(image="path") \u2014 View/read an image file directly
|
|
64487
|
+
vision(image="path", action="caption") \u2014 Describe image contents
|
|
64488
|
+
vision(image="path", action="query", prompt="question") \u2014 Visual QA
|
|
64489
|
+
vision(image="path", action="detect", prompt="object") \u2014 Find objects (bounding boxes)
|
|
64490
|
+
vision(image="path", action="point", prompt="element") \u2014 Find element center (for clicking)
|
|
64491
|
+
|
|
64492
|
+
DESKTOP INTERACTION PIPELINE:
|
|
64493
|
+
1. desktop_describe() \u2014 Screenshot + describe what's on screen
|
|
64494
|
+
2. desktop_click({ target: "element" }) \u2014 Find + click an element
|
|
64495
|
+
3. desktop_click({ target: "file.pdf", click_type: "double" }) \u2014 Double click to open
|
|
64496
|
+
4. desktop_click({ target: "icon", button: "right" }) \u2014 Right click for context menu
|
|
64497
|
+
Chain calls iteratively: describe \u2192 click \u2192 wait \u2192 describe \u2192 click next item
|
|
64498
|
+
|
|
64499
|
+
RULES:
|
|
64500
|
+
- Do NOT say you cannot see images \u2014 you can.
|
|
64501
|
+
- Use desktop_describe first to survey the screen, then desktop_click to interact.
|
|
64502
|
+
- After clicking, call desktop_describe again to verify the result.
|
|
64503
|
+
- For file operations: double-click to open, right-click for context menus.
|
|
64504
|
+
- Use delay_ms parameter if UI needs time to transition between clicks.
|
|
64456
64505
|
</vision-capabilities>`;
|
|
64457
64506
|
}
|
|
64458
64507
|
let localFirstOverride = false;
|
package/package.json
CHANGED