@intuned/browser-use-dev 0.0.0-stage → 0.1.2-dev.0

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.
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RESULT_TOOL_NAME = exports.NOT_EXECUTED_ERROR = exports.JAVASCRIPT_TOOL_NAME = exports.ActionSequencer = void 0;
7
+ exports.buildTools = buildTools;
8
+ var _ai = require("ai");
9
+ var _ajv = _interopRequireDefault(require("ajv"));
10
+ var _ajvFormats = _interopRequireDefault(require("ajv-formats"));
11
+ var _Logger = require("../common/Logger");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const RESULT_TOOL_NAME = exports.RESULT_TOOL_NAME = "submit_result";
14
+ const JAVASCRIPT_TOOL_NAME = exports.JAVASCRIPT_TOOL_NAME = "execute_javascript";
15
+ const BUILT_IN_TOOL_NAMES = new Set(["click", "double_click", "scroll", "type", "keypress", "wait", "move", "drag", "clear_field", "fill_field", "list_tabs", "screenshot"]);
16
+ const AUTO_SCREENSHOT_TOOLS = new Set(["scroll", "wait"]);
17
+ const pointProps = {
18
+ x: {
19
+ type: "number",
20
+ description: "X coordinate (CSS px)"
21
+ },
22
+ y: {
23
+ type: "number",
24
+ description: "Y coordinate (CSS px)"
25
+ }
26
+ };
27
+ const SCROLL_TOOL_DESCRIPTION = ["Scroll the screen in a direction by a number of scroll units, slowly and", "in steps so lazy-loaded content renders instead of being skipped. Pass", "(x, y) to scroll the container under that point (dialog bodies, inner", "panes); otherwise the current mouse position is used. A screenshot is", "taken automatically afterwards. DO NOT use PageUp/PageDown to scroll.", "", "One full page is exactly 8 scroll units high (for the main viewport;", "inner containers depend on their own size).", "- scroll_amount=7 (default mode): explore new pages — scrolls almost a", " full page while keeping some overlap with the previous view.", "- scroll_amount=1-3 (precision mode): fine-tune position for a specific", " element or navigate within a small content area.", "- scroll_amount=8+ (speed mode): rapidly traverse long, repetitive pages;", " scroll back if you overshoot.", "Tip: clear out any modals/popups before scrolling so your vision is clear."].join("\n");
28
+ const toScreenshotModelOutput = output => ({
29
+ type: "content",
30
+ value: [{
31
+ type: "text",
32
+ text: output.text
33
+ }, ...(output.screenshot ? [{
34
+ type: "media",
35
+ data: output.screenshot,
36
+ mediaType: "image/png"
37
+ }] : [])]
38
+ });
39
+ const NOT_EXECUTED_ERROR = exports.NOT_EXECUTED_ERROR = "Not executed: an earlier action in this turn failed. Look at the new screenshot and decide again.";
40
+ class ActionSequencer {
41
+ tail = Promise.resolve();
42
+ pending = 0;
43
+ failed = false;
44
+ get queued() {
45
+ return this.pending;
46
+ }
47
+ failRemaining() {
48
+ this.failed = true;
49
+ }
50
+ run(fn, {
51
+ evenAfterFailure = false
52
+ } = {}) {
53
+ this.pending += 1;
54
+ const result = this.tail.then(async () => {
55
+ if (this.failed && !evenAfterFailure) throw new Error(NOT_EXECUTED_ERROR);
56
+ try {
57
+ return await fn();
58
+ } catch (error) {
59
+ this.failed = true;
60
+ throw error;
61
+ }
62
+ });
63
+ this.tail = result.then(() => undefined, () => undefined).then(() => {
64
+ this.pending -= 1;
65
+ if (this.pending === 0) this.failed = false;
66
+ });
67
+ return result;
68
+ }
69
+ }
70
+ exports.ActionSequencer = ActionSequencer;
71
+ function actionTool(name, description, parameters, run, computer, sequencer) {
72
+ const attempt = async args => {
73
+ try {
74
+ return {
75
+ text: await run(args),
76
+ failed: false
77
+ };
78
+ } catch (e) {
79
+ sequencer.failRemaining();
80
+ return {
81
+ text: `Error: ${e instanceof Error ? e.message : String(e)}`,
82
+ failed: true
83
+ };
84
+ }
85
+ };
86
+ if (!AUTO_SCREENSHOT_TOOLS.has(name)) {
87
+ return (0, _ai.tool)({
88
+ description,
89
+ inputSchema: (0, _ai.jsonSchema)(parameters),
90
+ execute: async args => sequencer.run(async () => (await attempt(args)).text)
91
+ });
92
+ }
93
+ return (0, _ai.tool)({
94
+ description,
95
+ inputSchema: (0, _ai.jsonSchema)(parameters),
96
+ execute: async args => sequencer.run(async () => {
97
+ const {
98
+ text,
99
+ failed
100
+ } = await attempt(args);
101
+ return failed ? {
102
+ text
103
+ } : {
104
+ text,
105
+ screenshot: await computer.screenshot()
106
+ };
107
+ }),
108
+ toModelOutput: toScreenshotModelOutput
109
+ });
110
+ }
111
+ function buildTools(opts) {
112
+ const {
113
+ computer,
114
+ extraTools,
115
+ outputSchema,
116
+ onResultCaptured,
117
+ logSteps = true,
118
+ enableJavaScriptTool = false
119
+ } = opts;
120
+ const sequencer = new ActionSequencer();
121
+ const tools = {
122
+ click: actionTool("click", "Click at (x, y). Use click_count 2/3 for double/triple left clicks. " + "Use button 'back'/'forward' for browser navigation, 'wheel' for a " + "scroll click. Downloads and popup tabs triggered by the click are " + "detected and reported in the result.", {
123
+ type: "object",
124
+ properties: {
125
+ ...pointProps,
126
+ button: {
127
+ type: "string",
128
+ enum: ["left", "right", "middle", "back", "forward", "wheel"],
129
+ description: "Defaults to 'left'."
130
+ },
131
+ click_count: {
132
+ type: "number",
133
+ enum: [1, 2, 3],
134
+ description: "Number of clicks (left button only). Defaults to 1."
135
+ }
136
+ },
137
+ required: ["x", "y"],
138
+ additionalProperties: false
139
+ }, args => computer.click(args), computer, sequencer),
140
+ double_click: actionTool("double_click", "Double-click at (x, y).", {
141
+ type: "object",
142
+ properties: pointProps,
143
+ required: ["x", "y"],
144
+ additionalProperties: false
145
+ }, args => computer.double_click(args), computer, sequencer),
146
+ scroll: actionTool("scroll", SCROLL_TOOL_DESCRIPTION, {
147
+ type: "object",
148
+ properties: {
149
+ ...pointProps,
150
+ scroll_direction: {
151
+ type: "string",
152
+ enum: ["up", "down", "left", "right"],
153
+ description: "The direction to scroll the screen."
154
+ },
155
+ scroll_amount: {
156
+ type: "number",
157
+ description: "The number of scroll units (8 units ≈ one page)."
158
+ }
159
+ },
160
+ required: ["scroll_direction", "scroll_amount"],
161
+ additionalProperties: false
162
+ }, args => computer.scroll(args), computer, sequencer),
163
+ type: actionTool("type", "Type text at the current focus/cursor position, after whatever is already there. " + "Click the target field first. To replace a field's value use fill_field instead.", {
164
+ type: "object",
165
+ properties: {
166
+ text: {
167
+ type: "string"
168
+ }
169
+ },
170
+ required: ["text"],
171
+ additionalProperties: false
172
+ }, args => computer.type(args), computer, sequencer),
173
+ keypress: actionTool("keypress", "Press a key combination (e.g. ['ctrl', 'a']). Modifiers are held while " + "the final key is pressed, then released. 'cmd' is the platform's " + "primary shortcut modifier (Cmd on macOS, Ctrl elsewhere), so ['cmd', 'a'] " + "selects all everywhere. A single 'Home'/'End' is converted into a slow scroll to " + "the top/bottom so lazy-loaded content still renders.", {
174
+ type: "object",
175
+ properties: {
176
+ keys: {
177
+ type: "array",
178
+ items: {
179
+ type: "string"
180
+ }
181
+ }
182
+ },
183
+ required: ["keys"],
184
+ additionalProperties: false
185
+ }, args => computer.keypress(args), computer, sequencer),
186
+ wait: actionTool("wait", "Wait for `ms` milliseconds (default 1000) — e.g. to let an animation or a lazy-loaded section finish. " + "Returns a screenshot taken after the pause, so no separate screenshot call is needed.", {
187
+ type: "object",
188
+ properties: {
189
+ ms: {
190
+ type: "number"
191
+ }
192
+ },
193
+ additionalProperties: false
194
+ }, args => computer.wait(args), computer, sequencer),
195
+ move: actionTool("move", "Move the mouse to (x, y) without clicking — e.g. to trigger a hover effect.", {
196
+ type: "object",
197
+ properties: pointProps,
198
+ required: ["x", "y"],
199
+ additionalProperties: false
200
+ }, args => computer.move(args), computer, sequencer),
201
+ drag: actionTool("drag", "Drag the mouse along a path of points, pressed down for the whole path.", {
202
+ type: "object",
203
+ properties: {
204
+ path: {
205
+ type: "array",
206
+ items: {
207
+ type: "object",
208
+ properties: pointProps,
209
+ required: ["x", "y"],
210
+ additionalProperties: false
211
+ }
212
+ }
213
+ },
214
+ required: ["path"],
215
+ additionalProperties: false
216
+ }, args => computer.drag(args), computer, sequencer),
217
+ clear_field: actionTool("clear_field", "Clear a text input: click the field at (x, y), select all its text, and delete it. " + "Use this instead of pressing Backspace repeatedly. The result says whether the field is empty afterwards.", {
218
+ type: "object",
219
+ properties: pointProps,
220
+ required: ["x", "y"],
221
+ additionalProperties: false
222
+ }, args => computer.clear_field(args), computer, sequencer),
223
+ fill_field: actionTool("fill_field", "Set a text field's value in one step: click the field at (x, y), clear whatever it holds, " + "and type `text`. Prefer this over click + clear_field + type. The result reports the value " + "the field holds afterwards, so you can see if the page reformatted it.", {
224
+ type: "object",
225
+ properties: {
226
+ ...pointProps,
227
+ text: {
228
+ type: "string"
229
+ }
230
+ },
231
+ required: ["x", "y", "text"],
232
+ additionalProperties: false
233
+ }, args => computer.fill_field(args), computer, sequencer),
234
+ screenshot: (0, _ai.tool)({
235
+ description: "Take a screenshot of the current page. Call it at the end of a batch of actions, in the " + "same response, to see their result. scroll and wait already return a screenshot.",
236
+ inputSchema: (0, _ai.jsonSchema)({
237
+ type: "object",
238
+ properties: {},
239
+ additionalProperties: false
240
+ }),
241
+ execute: async () => sequencer.run(async () => ({
242
+ text: `CURRENT URL: ${computer.url()}`,
243
+ screenshot: await computer.screenshot()
244
+ }), {
245
+ evenAfterFailure: true
246
+ }),
247
+ toModelOutput: toScreenshotModelOutput
248
+ }),
249
+ list_tabs: (0, _ai.tool)({
250
+ description: "List all currently open browser tabs (index, url, title, and is_current " + "for the tab you are acting on). Use this to check whether a popup tab " + "has opened — do NOT use keyboard shortcuts to hunt for tabs.",
251
+ inputSchema: (0, _ai.jsonSchema)({
252
+ type: "object",
253
+ properties: {},
254
+ additionalProperties: false
255
+ }),
256
+ execute: async () => computer.list_tabs()
257
+ })
258
+ };
259
+ if (enableJavaScriptTool) {
260
+ tools[JAVASCRIPT_TOOL_NAME] = (0, _ai.tool)({
261
+ description: "Execute arbitrary JavaScript in the page. `code` is the body of an " + "async function — use `return <value>` to get a result back, and " + "`await` for async work. Browser events the code triggers (file " + "downloads, popup tabs) are reported in the result; call screenshot " + "if you need to see the page afterwards. An escape hatch for cases " + "the standard actions can't reach — prefer click/type/scroll when " + "they suffice.",
262
+ inputSchema: (0, _ai.jsonSchema)({
263
+ type: "object",
264
+ properties: {
265
+ code: {
266
+ type: "string"
267
+ }
268
+ },
269
+ required: ["code"],
270
+ additionalProperties: false
271
+ }),
272
+ execute: async ({
273
+ code
274
+ }) => sequencer.run(async () => {
275
+ let value;
276
+ let events = [];
277
+ try {
278
+ ({
279
+ value,
280
+ events
281
+ } = await computer.executeJavascript(code));
282
+ } catch (e) {
283
+ throw new Error(`JavaScript execution failed: ${e instanceof Error ? e.message : String(e)}`);
284
+ }
285
+ const valueText = value === undefined ? "undefined" : typeof value === "string" ? value : JSON.stringify(value);
286
+ return events.length > 0 ? `${valueText}\nEvents:\n${events.join("\n")}` : valueText;
287
+ })
288
+ });
289
+ }
290
+ for (const extra of extraTools ?? []) {
291
+ if (tools[extra.name] || extra.name === RESULT_TOOL_NAME || extra.name === JAVASCRIPT_TOOL_NAME) {
292
+ throw new Error(BUILT_IN_TOOL_NAMES.has(extra.name) ? `browser-use: tool name "${extra.name}" conflicts with a built-in tool` : extra.name === RESULT_TOOL_NAME ? `browser-use: tool name "${RESULT_TOOL_NAME}" is reserved for outputSchema results` : extra.name === JAVASCRIPT_TOOL_NAME ? `browser-use: tool name "${JAVASCRIPT_TOOL_NAME}" is reserved for the JavaScript execution tool` : `browser-use: duplicate tool name "${extra.name}" in tools option`);
293
+ }
294
+ tools[extra.name] = (0, _ai.tool)({
295
+ description: extra.description,
296
+ inputSchema: (0, _ai.jsonSchema)(extra.parameters),
297
+ execute: async args => sequencer.run(async () => {
298
+ if (logSteps) {
299
+ const argsText = args && Object.keys(args).length > 0 ? JSON.stringify(args) : "";
300
+ _Logger.logger.info(`[browser-use] tool: ${extra.name}(${argsText})`);
301
+ }
302
+ return extra.handler(args);
303
+ })
304
+ });
305
+ }
306
+ if (outputSchema) {
307
+ let validate;
308
+ try {
309
+ const ajv = new _ajv.default({
310
+ allErrors: true,
311
+ strict: false
312
+ });
313
+ (0, _ajvFormats.default)(ajv);
314
+ validate = ajv.compile(outputSchema);
315
+ } catch (e) {
316
+ throw new Error(`browser-use: invalid outputSchema: ${e instanceof Error ? e.message : String(e)}`);
317
+ }
318
+ tools[RESULT_TOOL_NAME] = (0, _ai.tool)({
319
+ description: "Submit the FINAL structured result of the task. Call this exactly " + "once, when the task is complete, with values matching the schema.",
320
+ inputSchema: (0, _ai.jsonSchema)(outputSchema),
321
+ execute: async args => {
322
+ if (!validate(args)) {
323
+ const errors = (validate.errors ?? []).map(err => {
324
+ const details = err.params && Object.keys(err.params).length > 0 ? ` (${JSON.stringify(err.params)})` : "";
325
+ return `${err.instancePath || "result"} ${err.message}${details}`;
326
+ }).join("; ");
327
+ const message = `the submitted result does not match the required schema: ${errors}. ` + `Fix the result and call ${RESULT_TOOL_NAME} again.`;
328
+ if (logSteps) _Logger.logger.warn(`[browser-use] rejected structured result: ${message}`);
329
+ throw new Error(message);
330
+ }
331
+ onResultCaptured(args);
332
+ if (logSteps) _Logger.logger.info(`[browser-use] structured result submitted: ${JSON.stringify(args)}`);
333
+ return "success";
334
+ }
335
+ });
336
+ }
337
+ return tools;
338
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.logger = void 0;
7
+ var _nodeUtil = require("node:util");
8
+ var _chalk = _interopRequireDefault(require("chalk"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ const format = _nodeUtil.formatWithOptions.bind(undefined, {
11
+ colors: true
12
+ });
13
+ const LOG_LEVEL_COLORS = {
14
+ TRACE: _chalk.default.gray,
15
+ DEBUG: _chalk.default.blue,
16
+ INFO: _chalk.default.green,
17
+ WARN: _chalk.default.yellow,
18
+ ERROR: _chalk.default.red
19
+ };
20
+ class Logger {
21
+ logFunction(entry) {
22
+ const {
23
+ level,
24
+ timestamp,
25
+ message,
26
+ meta
27
+ } = entry;
28
+ const date = new Date(timestamp);
29
+ const levelColor = LOG_LEVEL_COLORS[level];
30
+ if (meta === undefined) {
31
+ process.stderr.write(`${format(date)} [@intuned/browser-use][${levelColor(level)}] ${message}\n`);
32
+ } else {
33
+ process.stderr.write(`${format(date)} [@intuned/browser-use][${levelColor(level)}] ${message} ${format(meta)}\n`);
34
+ }
35
+ }
36
+ log(level, message, meta) {
37
+ this.logFunction({
38
+ level,
39
+ message,
40
+ meta: meta && Object.keys(meta).length === 0 ? undefined : meta,
41
+ timestamp: Date.now()
42
+ });
43
+ }
44
+ trace(message, meta) {
45
+ this.log("TRACE", message, meta);
46
+ }
47
+ debug(message, meta) {
48
+ this.log("DEBUG", message, meta);
49
+ }
50
+ info(message, meta) {
51
+ this.log("INFO", message, meta);
52
+ }
53
+ warn(message, meta) {
54
+ this.log("WARN", message, meta);
55
+ }
56
+ error(message, meta) {
57
+ this.log("ERROR", message, meta);
58
+ }
59
+ }
60
+ const logger = exports.logger = new Logger();
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createProviderInstance = createProviderInstance;
7
+ exports.detectProvider = detectProvider;
8
+ var _anthropic = require("@ai-sdk/anthropic");
9
+ var _openai = require("@ai-sdk/openai");
10
+ var _google = require("@ai-sdk/google");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
+ function detectProvider(model) {
13
+ const m = model.toLowerCase();
14
+ if (m.startsWith("claude")) return "anthropic";
15
+ if (m.startsWith("gemini")) return "google";
16
+ if (["gpt", "o1", "o3", "o4"].some(p => m.startsWith(p))) return "openai";
17
+ throw new Error(`browser-use: unsupported model provider for "${model}"`);
18
+ }
19
+ const ENV_KEYS = {
20
+ openai: "OPENAI_API_KEY",
21
+ anthropic: "ANTHROPIC_API_KEY",
22
+ google: "GOOGLE_API_KEY"
23
+ };
24
+ async function resolveGatewayConfig() {
25
+ try {
26
+ const runtime = await Promise.resolve().then(() => _interopRequireWildcard(require("@intuned/runtime")));
27
+ const getAiGatewayConfig = runtime.getAiGatewayConfig;
28
+ if (typeof getAiGatewayConfig !== "function") {
29
+ throw new Error("@intuned/runtime does not export getAiGatewayConfig. Please upgrade to a newer version.");
30
+ }
31
+ return getAiGatewayConfig();
32
+ } catch (error) {
33
+ throw new Error("No API key provided and not running in Intuned context. " + "Please provide an API key or ensure @intuned/runtime is installed and you're running within an Intuned workflow. " + `Error: ${error instanceof Error ? error.message : String(error)}`);
34
+ }
35
+ }
36
+ async function createProviderInstance(options) {
37
+ const {
38
+ model
39
+ } = options;
40
+ const provider = detectProvider(model);
41
+ const apiKey = options.apiKey ?? process.env[ENV_KEYS[provider]];
42
+ if (apiKey) {
43
+ switch (provider) {
44
+ case "openai":
45
+ return (0, _openai.createOpenAI)({
46
+ apiKey
47
+ });
48
+ case "anthropic":
49
+ return (0, _anthropic.createAnthropic)({
50
+ apiKey
51
+ });
52
+ case "google":
53
+ return (0, _google.createGoogleGenerativeAI)({
54
+ apiKey
55
+ });
56
+ }
57
+ }
58
+ const gw = await resolveGatewayConfig();
59
+ switch (provider) {
60
+ case "openai":
61
+ return (0, _openai.createOpenAI)({
62
+ apiKey: gw.apiKey,
63
+ baseURL: gw.baseUrl
64
+ });
65
+ case "anthropic":
66
+ return (0, _anthropic.createAnthropic)({
67
+ apiKey: gw.apiKey,
68
+ baseURL: `${gw.baseUrl}/v1`
69
+ });
70
+ case "google":
71
+ return (0, _google.createGoogleGenerativeAI)({
72
+ apiKey: gw.apiKey,
73
+ baseURL: gw.baseUrl
74
+ });
75
+ }
76
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.withNetworkSettled = withNetworkSettled;
7
+ var _Logger = require("./Logger");
8
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
9
+ let cachedHelper;
10
+ async function loadWithNetworkSettledWait() {
11
+ if (cachedHelper !== undefined) return cachedHelper;
12
+ try {
13
+ const mod = await Promise.resolve().then(() => _interopRequireWildcard(require("@intuned/browser")));
14
+ cachedHelper = mod.withNetworkSettledWait ?? null;
15
+ } catch {
16
+ cachedHelper = null;
17
+ }
18
+ if (cachedHelper === null) {
19
+ _Logger.logger.debug("[browser-use] @intuned/browser is not installed — falling back to Playwright networkidle waiting after actions");
20
+ }
21
+ return cachedHelper;
22
+ }
23
+ async function withNetworkSettled(fn, options) {
24
+ const helper = await loadWithNetworkSettledWait();
25
+ if (helper) return helper(fn, options);
26
+ const result = await fn(options.page);
27
+ await options.page.waitForLoadState("networkidle", {
28
+ timeout: options.timeoutInMs
29
+ }).catch(() => undefined);
30
+ return result;
31
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseCostInCents = parseCostInCents;
7
+ function parseCostInCents(headerValue) {
8
+ if (headerValue == null) return 0;
9
+ const raw = Array.isArray(headerValue) ? headerValue[0] : headerValue;
10
+ if (typeof raw !== "string") return 0;
11
+ const cost = parseFloat(raw);
12
+ return Number.isFinite(cost) ? cost : 0;
13
+ }
@@ -0,0 +1,8 @@
1
+ export { executeTask, BrowserUseError } from "./browser-use/export";
2
+
3
+ export type {
4
+ ExecuteTaskOptions,
5
+ BrowserUseTurnResult,
6
+ BrowserUseFunctionTool,
7
+ BrowserUseFrame,
8
+ } from "./browser-use/export";
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _browserUse = require("./browser-use");
7
+ Object.keys(_browserUse).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _browserUse[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _browserUse[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,6 @@
1
+ // Type declarations for the optional peer dependency @intuned/runtime.
2
+ // When the package is installed, its actual types are used instead.
3
+ declare module "@intuned/runtime" {
4
+ export function getExecutionContext(): unknown;
5
+ export function getAiGatewayConfig(): { baseUrl: string; apiKey: string };
6
+ }
package/package.json CHANGED
@@ -1,6 +1,85 @@
1
1
  {
2
2
  "name": "@intuned/browser-use-dev",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.2-dev.0",
4
+ "description": "Intuned SDK browser-use agent: drive a Playwright page with a vision-capable model",
5
+ "types": "./dist/index.d.ts",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "typesVersions": {
10
+ "*": {
11
+ "browser-use": [
12
+ "./dist/browser-use/index.d.ts"
13
+ ]
14
+ }
15
+ },
16
+ "exports": {
17
+ ".": "./dist/index.js",
18
+ "./browser-use": "./dist/browser-use/index.js"
19
+ },
20
+ "author": "Intuned Team",
21
+ "license": "Elastic-2.0",
22
+ "packageManager": "yarn@4.12.0",
23
+ "scripts": {
24
+ "build": "rm -rf dist && tsc -p tsconfig.json && yarn copy-dts && babel src --out-dir dist --extensions '.ts' --ignore 'src/**/*.d.ts' && node ../scripts/ensure-index-types.js browser-use",
25
+ "test": "vitest run",
26
+ "test:dev": "vitest",
27
+ "test:watch": "vitest",
28
+ "lint": "eslint .",
29
+ "fix": "eslint . --fix",
30
+ "copy-dts": "copyfiles -u 1 \"src/**/*.d.ts\" dist"
31
+ },
32
+ "dependencies": {
33
+ "@ai-sdk/anthropic": "2.0.91",
34
+ "@ai-sdk/google": "2.0.85",
35
+ "@ai-sdk/openai": "2.0.116",
36
+ "ai": "5.0.222",
37
+ "ajv": "8.18.0",
38
+ "ajv-formats": "2.1.1",
39
+ "chalk": "4.1.2",
40
+ "dotenv": "^16.3.1",
41
+ "tslib": "2.6.0",
42
+ "zod": "^3.25.76"
43
+ },
44
+ "devDependencies": {
45
+ "@babel/cli": "^7.23.4",
46
+ "@babel/core": "^7.23.7",
47
+ "@babel/plugin-transform-export-namespace-from": "^7.24.1",
48
+ "@babel/preset-env": "^7.23.7",
49
+ "@babel/preset-typescript": "^7.23.3",
50
+ "@intuned/browser": "0.1.19",
51
+ "@types/node": "^24.1.0",
52
+ "@typescript-eslint/eslint-plugin": "^5.47.1",
53
+ "@typescript-eslint/parser": "^7.5.0",
54
+ "copyfiles": "2.4.1",
55
+ "eslint": "7.32.0",
56
+ "eslint-plugin-deprecation": "^1.3.3",
57
+ "eslint-plugin-prettier": "^4.2.1",
58
+ "playwright": ">=1.46.0 <1.57",
59
+ "prettier": "^2.8.8",
60
+ "typescript": "5.4.4",
61
+ "vite": "^7.3.7",
62
+ "vitest": "^4.1.11"
63
+ },
64
+ "peerDependencies": {
65
+ "@intuned/browser": "*",
66
+ "@intuned/runtime": "*",
67
+ "playwright": ">=1.46.0 <1.62"
68
+ },
69
+ "peerDependenciesMeta": {
70
+ "@intuned/browser": {
71
+ "optional": true
72
+ },
73
+ "@intuned/runtime": {
74
+ "optional": true
75
+ }
76
+ },
77
+ "resolutions": {
78
+ "js-yaml": "3.15.2",
79
+ "fast-uri": "3.1.8",
80
+ "uuid": "11.1.1",
81
+ "nanoid": "3.3.18",
82
+ "esbuild": "0.28.2",
83
+ "vite": "7.3.7"
84
+ }
6
85
  }