Skip to content

Commit abdce8a

Browse files
committed
save
1 parent ecbd215 commit abdce8a

File tree

10 files changed

+364
-154
lines changed

10 files changed

+364
-154
lines changed

.fernignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# Specify files that shouldn't be modified by Fern
2-
src/CustomClient.ts
2+
src/wrapper/*
3+
examples/*
4+
.vscode/*

examples/run.ts

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,69 @@
11
#!/usr/bin/env -S npm run tsn -T
22

3-
import { BrowserUse } from 'browser-use-sdk';
4-
import { z } from 'zod';
3+
import { BrowserUseClient } from "browser-use-sdk";
4+
import { z } from "zod";
55

6-
import { env } from './utils';
6+
import { env } from "./utils";
77

88
env();
99

1010
// gets API Key from environment variable BROWSER_USE_API_KEY
11-
const browseruse = new BrowserUse();
11+
const browseruse = new BrowserUseClient({
12+
apiKey: process.env.BROWSER_USE_API_KEY!,
13+
environment: "production",
14+
});
1215

1316
async function basic() {
14-
console.log(`Basic: Running Task...`);
17+
console.log(`Basic: Running Task...`);
18+
19+
// Create Task
20+
const rsp = await browseruse.tasks.createTask({
21+
task: "What's the weather line in SF and what's the temperature?",
22+
});
1523

16-
// Create Task
17-
const rsp = await browseruse.tasks.run({
18-
task: "What's the weather line in SF and what's the temperature?",
19-
agentSettings: { llm: 'gemini-2.5-flash' },
20-
});
24+
const result = await rsp.complete();
2125

22-
console.log(`Basic: ${rsp.doneOutput}`);
26+
console.log(`Basic: ${result.output}`);
2327

24-
console.log(`Basic: DONE`);
28+
console.log(`Basic: DONE`);
2529
}
2630

2731
const HackerNewsResponse = z.object({
28-
title: z.string(),
29-
url: z.string(),
32+
title: z.string(),
33+
url: z.string(),
3034
});
3135

3236
const TaskOutput = z.object({
33-
posts: z.array(HackerNewsResponse),
37+
posts: z.array(HackerNewsResponse),
3438
});
3539

3640
async function structured() {
37-
console.log(`Structured: Running Task...`);
41+
console.log(`Structured: Running Task...`);
42+
43+
// Create Task
44+
const rsp = await browseruse.tasks.createTask({
45+
task: "Search for the top 10 Hacker News posts and return the title and url!",
46+
schema: TaskOutput,
47+
agentSettings: { llm: "gpt-4.1" },
48+
});
3849

39-
// Create Task
40-
const rsp = await browseruse.tasks.run({
41-
task: 'Search for the top 10 Hacker News posts and return the title and url!',
42-
schema: TaskOutput,
43-
agentSettings: { llm: 'gpt-4.1' },
44-
});
50+
const result = await rsp.complete();
4551

46-
const posts = rsp.parsedOutput?.posts;
52+
const posts = result.parsedOutput?.posts;
4753

48-
if (posts == null) {
49-
throw new Error('Structured: No posts found');
50-
}
54+
if (posts == null) {
55+
throw new Error("Structured: No posts found");
56+
}
5157

52-
console.log(`Structured: Top Hacker News posts:`);
58+
console.log(`Structured: Top Hacker News posts:`);
5359

54-
for (const post of posts) {
55-
console.log(` - ${post.title} - ${post.url}`);
56-
}
60+
for (const post of posts) {
61+
console.log(` - ${post.title} - ${post.url}`);
62+
}
5763

58-
console.log(`\nStructured: DONE`);
64+
console.log(`\nStructured: DONE`);
5965
}
6066

6167
basic()
62-
.then(() => structured())
63-
.catch(console.error);
68+
.then(() => structured())
69+
.catch(console.error);

examples/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": null,
5+
"rootDir": "..",
6+
"baseUrl": "..",
7+
"paths": {
8+
"browser-use-sdk": ["src"],
9+
"browser-use-sdk/*": ["src/*"]
10+
}
11+
},
12+
"include": ["../src", "../examples"],
13+
"exclude": []
14+
}

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export * as BrowserUse from "./api/index.js";
22
export { BrowserUseError, BrowserUseTimeoutError } from "./errors/index.js";
3-
export { BrowserUseClient } from "./Client.js";
3+
export { BrowserUseClient } from "./wrapper/BrowserUseClient.js";

src/wrapper/BrowserUseClient.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
import { BrowserUseClient as FernClient } from "../Client";
2+
import { BrowserUseTasks } from "./api/BrowserUseTasks";
23

3-
export class BrowserUseClient extends FernClient {}
4+
export class BrowserUseClient extends FernClient {
5+
protected _tasks: BrowserUseTasks | undefined;
6+
7+
public get tasks(): BrowserUseTasks {
8+
return (this._tasks ??= new BrowserUseTasks(this._options));
9+
}
10+
}

src/wrapper/api/BrowserUseTasks.ts

Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,99 @@
11
import * as BrowserUse from "../../api/index.js";
22
import * as core from "../../core/index.js";
33
import { Tasks } from "../../api/resources/tasks/client/Client.js";
4+
import {
5+
type CreateTaskRequestWithSchema,
6+
type WrappedTaskResponse,
7+
type TaskViewWithSchema,
8+
stringifyStructuredOutput,
9+
wrapCreateTaskResponse,
10+
parseStructuredTaskOutput,
11+
} from "wrapper/lib/parse.js";
12+
import { ZodType } from "zod";
413

514
export class BrowserUseTasks extends Tasks {
615
constructor(options: Tasks.Options) {
716
super(options);
817
}
918

19+
public createTask<T extends ZodType>(
20+
request: CreateTaskRequestWithSchema<T>,
21+
requestOptions?: Tasks.RequestOptions,
22+
): core.HttpResponsePromise<WrappedTaskResponse<T>>;
1023
public createTask(
1124
request: BrowserUse.CreateTaskRequest,
1225
requestOptions?: Tasks.RequestOptions,
13-
): core.HttpResponsePromise<BrowserUse.TaskCreatedResponse> {
14-
return super.createTask(request, requestOptions);
26+
): core.HttpResponsePromise<WrappedTaskResponse<null>>;
27+
public createTask(
28+
request: BrowserUse.CreateTaskRequest | CreateTaskRequestWithSchema<ZodType>,
29+
requestOptions?: Tasks.RequestOptions,
30+
): core.HttpResponsePromise<WrappedTaskResponse<ZodType>> | core.HttpResponsePromise<WrappedTaskResponse<null>> {
31+
if ("schema" in request) {
32+
const req: BrowserUse.CreateTaskRequest = {
33+
...request,
34+
structuredOutput: stringifyStructuredOutput(request.schema),
35+
};
36+
37+
const promise: Promise<core.WithRawResponse<WrappedTaskResponse<ZodType>>> = super
38+
.createTask(req, requestOptions)
39+
.withRawResponse()
40+
.then((res) => {
41+
const wrapped = wrapCreateTaskResponse(this, res.data, request.schema);
42+
43+
return {
44+
data: wrapped,
45+
rawResponse: res.rawResponse,
46+
};
47+
});
48+
49+
return core.HttpResponsePromise.fromPromise(promise);
50+
}
51+
52+
const promise: Promise<core.WithRawResponse<WrappedTaskResponse<null>>> = super
53+
.createTask(request, requestOptions)
54+
.withRawResponse()
55+
.then((res) => {
56+
const wrapped = wrapCreateTaskResponse(this, res.data, null);
57+
58+
return {
59+
data: wrapped,
60+
rawResponse: res.rawResponse,
61+
};
62+
});
63+
64+
return core.HttpResponsePromise.fromPromise(promise);
1565
}
1666

17-
/**
18-
* Get detailed information about a specific AI agent task.
19-
*
20-
* Retrieves comprehensive information about a task, including its current status,
21-
* progress, and detailed execution data. You can choose to get just the status
22-
* (for quick polling) or full details including steps and file information.
23-
*
24-
* Use this endpoint to:
25-
*
26-
* - Monitor task progress in real-time
27-
* - Review completed task results
28-
* - Debug failed tasks by examining steps
29-
* - Download output files and logs
30-
*
31-
* Args:
32-
*
33-
* - task_id: The unique identifier of the agent task
34-
*
35-
* Returns:
36-
*
37-
* - Complete task information
38-
*
39-
* Raises:
40-
*
41-
* - 404: If the user agent task doesn't exist
42-
*/
43-
retrieve<T extends ZodType>(
44-
req: { taskId: string; schema: T },
45-
options?: RequestOptions,
46-
): APIPromise<TaskViewWithSchema<T>>;
47-
retrieve(taskID: string, options?: RequestOptions): APIPromise<TaskView>;
48-
retrieve(req: string | { taskId: string; schema: ZodType }, options?: RequestOptions): APIPromise<unknown> {
49-
if (typeof req === "string") {
50-
return this._client.get(path`/tasks/${req}`, options);
67+
public getTask<T extends ZodType>(
68+
request: { taskId: string; schema: T },
69+
requestOptions?: Tasks.RequestOptions,
70+
): core.HttpResponsePromise<TaskViewWithSchema<T>>;
71+
public getTask(
72+
taskId: string,
73+
requestOptions?: Tasks.RequestOptions,
74+
): core.HttpResponsePromise<BrowserUse.TaskView>;
75+
public getTask(
76+
request: { taskId: string; schema: ZodType } | string,
77+
requestOptions?: Tasks.RequestOptions,
78+
): core.HttpResponsePromise<BrowserUse.TaskView | TaskViewWithSchema<ZodType>> {
79+
if (typeof request === "string") {
80+
return super.getTask(request, requestOptions);
5181
}
5282

53-
const { taskId, schema } = req;
83+
const { taskId, schema } = request;
84+
85+
const promise: Promise<core.WithRawResponse<TaskViewWithSchema<ZodType>>> = super
86+
.getTask(taskId, requestOptions)
87+
.withRawResponse()
88+
.then((res) => {
89+
const parsed = parseStructuredTaskOutput(res.data, schema);
90+
91+
return {
92+
data: parsed,
93+
rawResponse: res.rawResponse,
94+
};
95+
});
5496

55-
return this._client
56-
.get(path`/tasks/${taskId}`, options)
57-
._thenUnwrap((rsp) => parseStructuredTaskOutput(rsp as TaskView, schema));
97+
return core.HttpResponsePromise.fromPromise(promise);
5898
}
5999
}

src/wrapper/lib/bin/auth.ts

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,62 @@
1-
import * as dotenv from '@dotenvx/dotenvx';
1+
import * as dotenv from "@dotenvx/dotenvx";
2+
import { BrowserUseClient } from "../../../Client.js";
23

3-
import { BrowserUse } from '../../';
4-
5-
const API_KEY_ENV_VAR_KEY = 'BROWSER_USE_API_KEY';
4+
const API_KEY_ENV_VAR_KEY = "BROWSER_USE_API_KEY";
65

76
/**
87
* Creates a new BrowserUse client with the API key from the environment variable.
98
*/
109
export function createBrowserUseClient() {
11-
let apiKey: string | null = null;
10+
let apiKey: string | null = null;
1211

13-
if (process.env[API_KEY_ENV_VAR_KEY]) {
14-
apiKey = process.env[API_KEY_ENV_VAR_KEY];
15-
}
12+
if (process.env[API_KEY_ENV_VAR_KEY]) {
13+
apiKey = process.env[API_KEY_ENV_VAR_KEY];
14+
}
1615

17-
if (apiKey == null) {
18-
const env = dotenv.config({ path: '.env' });
16+
if (apiKey == null) {
17+
const env = dotenv.config({ path: ".env" });
1918

20-
const envApiKey = env.parsed?.[API_KEY_ENV_VAR_KEY];
19+
const envApiKey = env.parsed?.[API_KEY_ENV_VAR_KEY];
2120

22-
if (envApiKey) {
23-
apiKey = envApiKey;
21+
if (envApiKey) {
22+
apiKey = envApiKey;
23+
}
2424
}
25-
}
2625

27-
if (apiKey == null) {
28-
console.error(`Missing ${API_KEY_ENV_VAR_KEY} environment variable!`);
29-
process.exit(1);
30-
}
26+
if (apiKey == null) {
27+
console.error(`Missing ${API_KEY_ENV_VAR_KEY} environment variable!`);
28+
process.exit(1);
29+
}
3130

32-
return new BrowserUse({ apiKey });
31+
return new BrowserUseClient({ apiKey, environment: "production" });
3332
}
3433

35-
const SECRET_ENV_VAR_KEY = 'SECRET_KEY';
34+
const SECRET_ENV_VAR_KEY = "SECRET_KEY";
3635

3736
/**
3837
* Loads the Browser Use webhook secret from the environment variable.
3938
*/
4039
export function getBrowserUseWebhookSecret() {
41-
let secret: string | null = null;
40+
let secret: string | null = null;
4241

43-
if (process.env[SECRET_ENV_VAR_KEY]) {
44-
secret = process.env[SECRET_ENV_VAR_KEY];
45-
}
42+
if (process.env[SECRET_ENV_VAR_KEY]) {
43+
secret = process.env[SECRET_ENV_VAR_KEY];
44+
}
4645

47-
if (secret == null) {
48-
const env = dotenv.config({ path: '.env' });
46+
if (secret == null) {
47+
const env = dotenv.config({ path: ".env" });
4948

50-
const envSecret = env.parsed?.[SECRET_ENV_VAR_KEY];
49+
const envSecret = env.parsed?.[SECRET_ENV_VAR_KEY];
5150

52-
if (envSecret) {
53-
secret = envSecret;
51+
if (envSecret) {
52+
secret = envSecret;
53+
}
5454
}
55-
}
5655

57-
if (secret == null) {
58-
console.error(`Missing ${SECRET_ENV_VAR_KEY} environment variable!`);
59-
process.exit(1);
60-
}
56+
if (secret == null) {
57+
console.error(`Missing ${SECRET_ENV_VAR_KEY} environment variable!`);
58+
process.exit(1);
59+
}
6160

62-
return secret;
61+
return secret;
6362
}

0 commit comments

Comments
 (0)