open-agents-ai 0.187.573 → 0.187.574
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 +233 -37
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -252600,7 +252600,9 @@ async function probeService() {
|
|
|
252600
252600
|
try {
|
|
252601
252601
|
const controller = new AbortController();
|
|
252602
252602
|
const timeout2 = setTimeout(() => controller.abort(), 3e3);
|
|
252603
|
-
const res = await fetch(`${BASE_URL}/health`, {
|
|
252603
|
+
const res = await fetch(`${BASE_URL}/health`, {
|
|
252604
|
+
signal: controller.signal
|
|
252605
|
+
});
|
|
252604
252606
|
clearTimeout(timeout2);
|
|
252605
252607
|
return res.ok;
|
|
252606
252608
|
} catch {
|
|
@@ -252610,7 +252612,10 @@ async function probeService() {
|
|
|
252610
252612
|
function findPython3() {
|
|
252611
252613
|
for (const cmd of ["python3", "python"]) {
|
|
252612
252614
|
try {
|
|
252613
|
-
const ver = execSync19(`${cmd} --version 2>&1`, {
|
|
252615
|
+
const ver = execSync19(`${cmd} --version 2>&1`, {
|
|
252616
|
+
stdio: "pipe",
|
|
252617
|
+
timeout: 5e3
|
|
252618
|
+
}).toString().trim();
|
|
252614
252619
|
if (ver.includes("Python 3"))
|
|
252615
252620
|
return cmd;
|
|
252616
252621
|
} catch {
|
|
@@ -252682,7 +252687,10 @@ async function ensureSession() {
|
|
|
252682
252687
|
});
|
|
252683
252688
|
const data = await res.json();
|
|
252684
252689
|
if (!data.ok)
|
|
252685
|
-
return {
|
|
252690
|
+
return {
|
|
252691
|
+
error: String(data.message ?? "Failed to start browser session"),
|
|
252692
|
+
sessionId: ""
|
|
252693
|
+
};
|
|
252686
252694
|
activeSessionId = data.session_id;
|
|
252687
252695
|
return { sessionId: activeSessionId };
|
|
252688
252696
|
}
|
|
@@ -252828,7 +252836,22 @@ var init_browser_action = __esm({
|
|
|
252828
252836
|
properties: {
|
|
252829
252837
|
action: {
|
|
252830
252838
|
type: "string",
|
|
252831
|
-
enum: [
|
|
252839
|
+
enum: [
|
|
252840
|
+
"navigate",
|
|
252841
|
+
"click",
|
|
252842
|
+
"click_xy",
|
|
252843
|
+
"type",
|
|
252844
|
+
"screenshot",
|
|
252845
|
+
"dom",
|
|
252846
|
+
"dom_summary",
|
|
252847
|
+
"vision_click",
|
|
252848
|
+
"scroll",
|
|
252849
|
+
"scroll_up",
|
|
252850
|
+
"scroll_down",
|
|
252851
|
+
"back",
|
|
252852
|
+
"forward",
|
|
252853
|
+
"close"
|
|
252854
|
+
],
|
|
252832
252855
|
description: "Browser action to perform. Key actions:\n- 'dom_summary': compact view of interactive elements (~1KB vs 200KB raw DOM)\n- 'vision_click': screenshot the page, use Moondream vision to find an element by description, then click it. Pass the element description in 'text' parameter (e.g. text='the login button'). This is the visual grounding loop from SeeAct.\n- 'click': click by CSS selector (fastest when you know the selector)\n- 'click_xy': click at pixel coordinates (when you have exact coords)"
|
|
252833
252856
|
},
|
|
252834
252857
|
url: {
|
|
@@ -252858,12 +252881,44 @@ var init_browser_action = __esm({
|
|
|
252858
252881
|
},
|
|
252859
252882
|
required: ["action"]
|
|
252860
252883
|
};
|
|
252884
|
+
/** TASK-CLEANUP: gracefully close the browser session when the task completes. */
|
|
252885
|
+
async cleanup() {
|
|
252886
|
+
if (activeSessionId) {
|
|
252887
|
+
try {
|
|
252888
|
+
const res = await fetch(`${BASE_URL}/session/close`, {
|
|
252889
|
+
method: "POST",
|
|
252890
|
+
headers: { "Content-Type": "application/json" },
|
|
252891
|
+
body: JSON.stringify({ sid: activeSessionId }),
|
|
252892
|
+
signal: AbortSignal.timeout(5e3)
|
|
252893
|
+
});
|
|
252894
|
+
await res.json();
|
|
252895
|
+
} catch {
|
|
252896
|
+
}
|
|
252897
|
+
activeSessionId = null;
|
|
252898
|
+
}
|
|
252899
|
+
if (serviceProcess && serviceProcess.pid && !serviceProcess.killed) {
|
|
252900
|
+
try {
|
|
252901
|
+
process.kill(-serviceProcess.pid, "SIGKILL");
|
|
252902
|
+
} catch {
|
|
252903
|
+
}
|
|
252904
|
+
try {
|
|
252905
|
+
serviceProcess.kill("SIGKILL");
|
|
252906
|
+
} catch {
|
|
252907
|
+
}
|
|
252908
|
+
serviceProcess = null;
|
|
252909
|
+
}
|
|
252910
|
+
}
|
|
252861
252911
|
async execute(args) {
|
|
252862
252912
|
const start2 = Date.now();
|
|
252863
252913
|
const action = args.action;
|
|
252864
252914
|
const launchErr = await launchService();
|
|
252865
252915
|
if (launchErr) {
|
|
252866
|
-
return {
|
|
252916
|
+
return {
|
|
252917
|
+
success: false,
|
|
252918
|
+
output: "",
|
|
252919
|
+
error: launchErr,
|
|
252920
|
+
durationMs: Date.now() - start2
|
|
252921
|
+
};
|
|
252867
252922
|
}
|
|
252868
252923
|
if (action === "close") {
|
|
252869
252924
|
if (activeSessionId) {
|
|
@@ -252873,21 +252928,41 @@ var init_browser_action = __esm({
|
|
|
252873
252928
|
}
|
|
252874
252929
|
activeSessionId = null;
|
|
252875
252930
|
}
|
|
252876
|
-
return {
|
|
252931
|
+
return {
|
|
252932
|
+
success: true,
|
|
252933
|
+
output: "Browser session closed.",
|
|
252934
|
+
durationMs: Date.now() - start2
|
|
252935
|
+
};
|
|
252877
252936
|
}
|
|
252878
252937
|
const session = await ensureSession();
|
|
252879
252938
|
if (session.error) {
|
|
252880
|
-
return {
|
|
252939
|
+
return {
|
|
252940
|
+
success: false,
|
|
252941
|
+
output: "",
|
|
252942
|
+
error: session.error,
|
|
252943
|
+
durationMs: Date.now() - start2
|
|
252944
|
+
};
|
|
252881
252945
|
}
|
|
252882
252946
|
try {
|
|
252883
252947
|
let result;
|
|
252884
252948
|
switch (action) {
|
|
252885
252949
|
case "navigate": {
|
|
252886
252950
|
if (!args.url)
|
|
252887
|
-
return {
|
|
252888
|
-
|
|
252951
|
+
return {
|
|
252952
|
+
success: false,
|
|
252953
|
+
output: "",
|
|
252954
|
+
error: "url is required for navigate action",
|
|
252955
|
+
durationMs: Date.now() - start2
|
|
252956
|
+
};
|
|
252957
|
+
result = await apiCall("/navigate", "POST", {
|
|
252958
|
+
url: args.url
|
|
252959
|
+
});
|
|
252889
252960
|
if (result.ok) {
|
|
252890
|
-
return {
|
|
252961
|
+
return {
|
|
252962
|
+
success: true,
|
|
252963
|
+
output: `Navigated to ${args.url}`,
|
|
252964
|
+
durationMs: Date.now() - start2
|
|
252965
|
+
};
|
|
252891
252966
|
}
|
|
252892
252967
|
const navMsg = String(result.message ?? "Navigation failed");
|
|
252893
252968
|
const navHint = navMsg.toLowerCase().includes("connection") || navMsg.toLowerCase().includes("refused") || navMsg.toLowerCase().includes("err_connection") ? " (the URL appears unreachable — check if the target server is running and accepting connections)" : navMsg.toLowerCase().includes("timeout") ? " (page load timed out — try again or use a different URL)" : "";
|
|
@@ -252900,10 +252975,21 @@ var init_browser_action = __esm({
|
|
|
252900
252975
|
}
|
|
252901
252976
|
case "click": {
|
|
252902
252977
|
if (!args.selector)
|
|
252903
|
-
return {
|
|
252904
|
-
|
|
252978
|
+
return {
|
|
252979
|
+
success: false,
|
|
252980
|
+
output: "",
|
|
252981
|
+
error: "selector is required for click action",
|
|
252982
|
+
durationMs: Date.now() - start2
|
|
252983
|
+
};
|
|
252984
|
+
result = await apiCall("/click", "POST", {
|
|
252985
|
+
selector: args.selector
|
|
252986
|
+
});
|
|
252905
252987
|
if (result.ok) {
|
|
252906
|
-
return {
|
|
252988
|
+
return {
|
|
252989
|
+
success: true,
|
|
252990
|
+
output: `Clicked element: ${args.selector}`,
|
|
252991
|
+
durationMs: Date.now() - start2
|
|
252992
|
+
};
|
|
252907
252993
|
}
|
|
252908
252994
|
const clickMsg = String(result.message ?? "Click failed");
|
|
252909
252995
|
return {
|
|
@@ -252915,10 +253001,19 @@ var init_browser_action = __esm({
|
|
|
252915
253001
|
}
|
|
252916
253002
|
case "click_xy": {
|
|
252917
253003
|
if (args.x == null || args.y == null)
|
|
252918
|
-
return {
|
|
253004
|
+
return {
|
|
253005
|
+
success: false,
|
|
253006
|
+
output: "",
|
|
253007
|
+
error: "x and y are required for click_xy action",
|
|
253008
|
+
durationMs: Date.now() - start2
|
|
253009
|
+
};
|
|
252919
253010
|
result = await apiCall("/click_xy", "POST", { x: args.x, y: args.y });
|
|
252920
253011
|
if (result.ok) {
|
|
252921
|
-
return {
|
|
253012
|
+
return {
|
|
253013
|
+
success: true,
|
|
253014
|
+
output: `Clicked at (${args.x}, ${args.y})`,
|
|
253015
|
+
durationMs: Date.now() - start2
|
|
253016
|
+
};
|
|
252922
253017
|
}
|
|
252923
253018
|
const xyMsg = String(result.message ?? "Click failed");
|
|
252924
253019
|
return {
|
|
@@ -252930,10 +253025,22 @@ var init_browser_action = __esm({
|
|
|
252930
253025
|
}
|
|
252931
253026
|
case "type": {
|
|
252932
253027
|
if (!args.selector || !args.text)
|
|
252933
|
-
return {
|
|
252934
|
-
|
|
253028
|
+
return {
|
|
253029
|
+
success: false,
|
|
253030
|
+
output: "",
|
|
253031
|
+
error: "selector and text are required for type action",
|
|
253032
|
+
durationMs: Date.now() - start2
|
|
253033
|
+
};
|
|
253034
|
+
result = await apiCall("/type", "POST", {
|
|
253035
|
+
selector: args.selector,
|
|
253036
|
+
text: args.text
|
|
253037
|
+
});
|
|
252935
253038
|
if (result.ok) {
|
|
252936
|
-
return {
|
|
253039
|
+
return {
|
|
253040
|
+
success: true,
|
|
253041
|
+
output: `Typed "${args.text.slice(0, 50)}" into ${args.selector}`,
|
|
253042
|
+
durationMs: Date.now() - start2
|
|
253043
|
+
};
|
|
252937
253044
|
}
|
|
252938
253045
|
const typeMsg = String(result.message ?? "Type failed");
|
|
252939
253046
|
return {
|
|
@@ -252981,16 +253088,30 @@ var init_browser_action = __esm({
|
|
|
252981
253088
|
durationMs: Date.now() - start2
|
|
252982
253089
|
};
|
|
252983
253090
|
}
|
|
252984
|
-
return {
|
|
253091
|
+
return {
|
|
253092
|
+
success: false,
|
|
253093
|
+
output: "",
|
|
253094
|
+
error: "Screenshot failed",
|
|
253095
|
+
durationMs: Date.now() - start2
|
|
253096
|
+
};
|
|
252985
253097
|
}
|
|
252986
253098
|
case "dom": {
|
|
252987
253099
|
result = await apiCall("/dom", "GET");
|
|
252988
253100
|
const dom = result.dom;
|
|
252989
253101
|
if (dom) {
|
|
252990
253102
|
const truncated = dom.length > 5e4 ? dom.slice(0, 5e4) + "\n... (truncated)" : dom;
|
|
252991
|
-
return {
|
|
253103
|
+
return {
|
|
253104
|
+
success: true,
|
|
253105
|
+
output: truncated,
|
|
253106
|
+
durationMs: Date.now() - start2
|
|
253107
|
+
};
|
|
252992
253108
|
}
|
|
252993
|
-
return {
|
|
253109
|
+
return {
|
|
253110
|
+
success: false,
|
|
253111
|
+
output: "",
|
|
253112
|
+
error: "DOM capture failed",
|
|
253113
|
+
durationMs: Date.now() - start2
|
|
253114
|
+
};
|
|
252994
253115
|
}
|
|
252995
253116
|
// dom_summary: Research-grounded DOM downsampling
|
|
252996
253117
|
// Paper: AgentOccam (arXiv:2410.13825, ICLR 2025) — pivotal node extraction
|
|
@@ -253004,9 +253125,18 @@ var init_browser_action = __esm({
|
|
|
253004
253125
|
result = await apiCall("/dom", "GET");
|
|
253005
253126
|
const rawDom = result.dom;
|
|
253006
253127
|
if (!rawDom)
|
|
253007
|
-
return {
|
|
253128
|
+
return {
|
|
253129
|
+
success: false,
|
|
253130
|
+
output: "",
|
|
253131
|
+
error: "DOM capture failed",
|
|
253132
|
+
durationMs: Date.now() - start2
|
|
253133
|
+
};
|
|
253008
253134
|
const summary = downsampleDom(rawDom);
|
|
253009
|
-
return {
|
|
253135
|
+
return {
|
|
253136
|
+
success: true,
|
|
253137
|
+
output: summary,
|
|
253138
|
+
durationMs: Date.now() - start2
|
|
253139
|
+
};
|
|
253010
253140
|
}
|
|
253011
253141
|
// vision_click: Screenshot → Moondream point detection → Click
|
|
253012
253142
|
// Paper: SeeAct (arXiv:2401.01614) — visual grounding for web agents
|
|
@@ -253019,14 +253149,24 @@ var init_browser_action = __esm({
|
|
|
253019
253149
|
case "vision_click": {
|
|
253020
253150
|
const target = args.text;
|
|
253021
253151
|
if (!target)
|
|
253022
|
-
return {
|
|
253152
|
+
return {
|
|
253153
|
+
success: false,
|
|
253154
|
+
output: "",
|
|
253155
|
+
error: "text parameter is required for vision_click — describe what to click (e.g. 'the login button')",
|
|
253156
|
+
durationMs: Date.now() - start2
|
|
253157
|
+
};
|
|
253023
253158
|
const ssResult = await apiCall("/screenshot", "GET");
|
|
253024
253159
|
const ssB64 = ssResult.b64;
|
|
253025
253160
|
const ssWidth = ssResult.width || 1280;
|
|
253026
253161
|
const ssHeight = ssResult.height || 720;
|
|
253027
253162
|
const ssFile = ssResult.file;
|
|
253028
253163
|
if (!ssB64 && !ssFile) {
|
|
253029
|
-
return {
|
|
253164
|
+
return {
|
|
253165
|
+
success: false,
|
|
253166
|
+
output: "",
|
|
253167
|
+
error: "Screenshot failed — cannot perform vision click",
|
|
253168
|
+
durationMs: Date.now() - start2
|
|
253169
|
+
};
|
|
253030
253170
|
}
|
|
253031
253171
|
let imagePath = "";
|
|
253032
253172
|
if (ssFile) {
|
|
@@ -253038,7 +253178,12 @@ var init_browser_action = __esm({
|
|
|
253038
253178
|
wfs(tmpPath, fileBuffer);
|
|
253039
253179
|
imagePath = tmpPath;
|
|
253040
253180
|
} catch (e2) {
|
|
253041
|
-
return {
|
|
253181
|
+
return {
|
|
253182
|
+
success: false,
|
|
253183
|
+
output: "",
|
|
253184
|
+
error: `Failed to save screenshot: ${e2}`,
|
|
253185
|
+
durationMs: Date.now() - start2
|
|
253186
|
+
};
|
|
253042
253187
|
}
|
|
253043
253188
|
} else if (ssB64) {
|
|
253044
253189
|
const tmpPath = join41(process.env["TMPDIR"] || "/tmp", `oa-vision-click-${Date.now()}.png`);
|
|
@@ -253056,7 +253201,12 @@ var init_browser_action = __esm({
|
|
|
253056
253201
|
prompt: target
|
|
253057
253202
|
});
|
|
253058
253203
|
if (!visionResult.success) {
|
|
253059
|
-
return {
|
|
253204
|
+
return {
|
|
253205
|
+
success: false,
|
|
253206
|
+
output: `Vision could not find "${target}" on the page. Try using dom_summary to find the CSS selector instead.`,
|
|
253207
|
+
error: visionResult.error,
|
|
253208
|
+
durationMs: Date.now() - start2
|
|
253209
|
+
};
|
|
253060
253210
|
}
|
|
253061
253211
|
const coordMatch = visionResult.output.match(/\((\d+\.?\d*),\s*(\d+\.?\d*)\)/);
|
|
253062
253212
|
if (coordMatch) {
|
|
@@ -253066,10 +253216,19 @@ var init_browser_action = __esm({
|
|
|
253066
253216
|
pointY = Math.round(normY * ssHeight);
|
|
253067
253217
|
}
|
|
253068
253218
|
} catch (e2) {
|
|
253069
|
-
return {
|
|
253219
|
+
return {
|
|
253220
|
+
success: false,
|
|
253221
|
+
output: "",
|
|
253222
|
+
error: `Vision detection failed: ${e2}`,
|
|
253223
|
+
durationMs: Date.now() - start2
|
|
253224
|
+
};
|
|
253070
253225
|
}
|
|
253071
253226
|
if (pointX < 0 || pointY < 0) {
|
|
253072
|
-
return {
|
|
253227
|
+
return {
|
|
253228
|
+
success: false,
|
|
253229
|
+
output: `Could not determine click coordinates for "${target}". Vision returned no valid points.`,
|
|
253230
|
+
durationMs: Date.now() - start2
|
|
253231
|
+
};
|
|
253073
253232
|
}
|
|
253074
253233
|
const clickResult = await apiCall("/click_xy", "POST", {
|
|
253075
253234
|
x: pointX,
|
|
@@ -253092,22 +253251,49 @@ var init_browser_action = __esm({
|
|
|
253092
253251
|
};
|
|
253093
253252
|
}
|
|
253094
253253
|
case "scroll":
|
|
253095
|
-
result = await apiCall("/scroll", "POST", {
|
|
253096
|
-
|
|
253254
|
+
result = await apiCall("/scroll", "POST", {
|
|
253255
|
+
amount: args.amount ?? 600
|
|
253256
|
+
});
|
|
253257
|
+
return {
|
|
253258
|
+
success: !!result.ok,
|
|
253259
|
+
output: `Scrolled ${args.amount ?? 600}px`,
|
|
253260
|
+
durationMs: Date.now() - start2
|
|
253261
|
+
};
|
|
253097
253262
|
case "scroll_up":
|
|
253098
253263
|
result = await apiCall("/scroll/up", "POST");
|
|
253099
|
-
return {
|
|
253264
|
+
return {
|
|
253265
|
+
success: !!result.ok,
|
|
253266
|
+
output: "Scrolled up",
|
|
253267
|
+
durationMs: Date.now() - start2
|
|
253268
|
+
};
|
|
253100
253269
|
case "scroll_down":
|
|
253101
253270
|
result = await apiCall("/scroll/down", "POST");
|
|
253102
|
-
return {
|
|
253271
|
+
return {
|
|
253272
|
+
success: !!result.ok,
|
|
253273
|
+
output: "Scrolled down",
|
|
253274
|
+
durationMs: Date.now() - start2
|
|
253275
|
+
};
|
|
253103
253276
|
case "back":
|
|
253104
253277
|
result = await apiCall("/history/back", "POST");
|
|
253105
|
-
return {
|
|
253278
|
+
return {
|
|
253279
|
+
success: !!result.ok,
|
|
253280
|
+
output: "Navigated back",
|
|
253281
|
+
durationMs: Date.now() - start2
|
|
253282
|
+
};
|
|
253106
253283
|
case "forward":
|
|
253107
253284
|
result = await apiCall("/history/forward", "POST");
|
|
253108
|
-
return {
|
|
253285
|
+
return {
|
|
253286
|
+
success: !!result.ok,
|
|
253287
|
+
output: "Navigated forward",
|
|
253288
|
+
durationMs: Date.now() - start2
|
|
253289
|
+
};
|
|
253109
253290
|
default:
|
|
253110
|
-
return {
|
|
253291
|
+
return {
|
|
253292
|
+
success: false,
|
|
253293
|
+
output: "",
|
|
253294
|
+
error: `Unknown action: ${action}. Available: navigate, click, click_xy, type, screenshot, dom, scroll, scroll_up, scroll_down, back, forward, close`,
|
|
253295
|
+
durationMs: Date.now() - start2
|
|
253296
|
+
};
|
|
253111
253297
|
}
|
|
253112
253298
|
} catch (err) {
|
|
253113
253299
|
return {
|
|
@@ -534893,6 +535079,14 @@ ${sr.result.output}`;
|
|
|
534893
535079
|
} else {
|
|
534894
535080
|
completed = true;
|
|
534895
535081
|
summary = extractTaskCompleteSummary(r2.tc.arguments);
|
|
535082
|
+
for (const tool of this.tools.values()) {
|
|
535083
|
+
if (tool.cleanup) {
|
|
535084
|
+
try {
|
|
535085
|
+
await tool.cleanup();
|
|
535086
|
+
} catch {
|
|
535087
|
+
}
|
|
535088
|
+
}
|
|
535089
|
+
}
|
|
534896
535090
|
if (summary && !this._assistantTextEmitted) {
|
|
534897
535091
|
this.emit({
|
|
534898
535092
|
type: "assistant_text",
|
|
@@ -613853,7 +614047,9 @@ function adaptTool6(tool) {
|
|
|
613853
614047
|
output: result.output,
|
|
613854
614048
|
error: result.error
|
|
613855
614049
|
};
|
|
613856
|
-
}
|
|
614050
|
+
},
|
|
614051
|
+
// Pass through lifecycle hooks from the underlying Tool implementation
|
|
614052
|
+
cleanup: tool.cleanup
|
|
613857
614053
|
};
|
|
613858
614054
|
}
|
|
613859
614055
|
function scanForSessionSignals(toolOutput) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
3
|
+
"version": "0.187.574",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "open-agents-ai",
|
|
9
|
-
"version": "0.187.
|
|
9
|
+
"version": "0.187.574",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED