Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { HyperAgentService } from "./services/agents/hyper-agent";
import { TeamService } from "./services/team";
import { ComputerActionService } from "./services/computer-action";
import { GeminiComputerUseService } from "./services/agents/gemini-computer-use";
import { TaskService } from "./services/agents/task";
import { WebService } from "./services/web";
import { SandboxesService } from "./services/sandboxes";
import { VolumesService } from "./services/volumes";
Expand Down Expand Up @@ -67,6 +68,7 @@ export class HyperbrowserClient {
cua: CuaService;
hyperAgent: HyperAgentService;
geminiComputerUse: GeminiComputerUseService;
task: TaskService;
};
public readonly team: TeamService;
public readonly computerAction: ComputerActionService;
Expand Down Expand Up @@ -102,6 +104,7 @@ export class HyperbrowserClient {
cua: new CuaService(apiKey, baseUrl, timeout),
hyperAgent: new HyperAgentService(apiKey, baseUrl, timeout),
geminiComputerUse: new GeminiComputerUseService(apiKey, baseUrl, timeout),
task: new TaskService(apiKey, baseUrl, timeout),
};
}
}
23 changes: 23 additions & 0 deletions src/services/agents/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { HyperbrowserError } from "../../client";
import { AgentTaskListParams, AgentTaskListResponse } from "../../types/agents/task";
import { BaseService } from "../base";

export abstract class AgentTaskListService extends BaseService {
protected abstract readonly taskPath: string;
protected abstract readonly taskLabel: string;

async list(params: AgentTaskListParams = {}): Promise<AgentTaskListResponse> {
try {
return await this.request<AgentTaskListResponse>(`/task/${this.taskPath}`, undefined, {
task: params.task,
page: params.page,
limit: params.limit,
});
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError(`Failed to list ${this.taskLabel} task jobs`, undefined);
}
}
}
7 changes: 5 additions & 2 deletions src/services/agents/browser-use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import {
BrowserUseTaskStatusResponse,
} from "../../types/agents/browser-use";
import { isZodSchema, sleep } from "../../utils";
import { BaseService } from "../base";
import { AgentTaskListService } from "./base";

export class BrowserUseService extends AgentTaskListService {
protected readonly taskPath = "browser-use";
protected readonly taskLabel = "browser-use";

export class BrowserUseService extends BaseService {
/**
* Start a new browser-use task job
* @param params The parameters for the task job
Expand Down
7 changes: 5 additions & 2 deletions src/services/agents/claude-computer-use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { HyperbrowserError } from "../../client";
import { BasicResponse } from "../../types";
import { POLLING_ATTEMPTS } from "../../types/constants";
import { sleep } from "../../utils";
import { BaseService } from "../base";
import { AgentTaskListService } from "./base";
import {
ClaudeComputerUseTaskResponse,
ClaudeComputerUseTaskStatusResponse,
StartClaudeComputerUseTaskParams,
StartClaudeComputerUseTaskResponse,
} from "../../types/agents/claude-computer-use";

export class ClaudeComputerUseService extends BaseService {
export class ClaudeComputerUseService extends AgentTaskListService {
protected readonly taskPath = "claude-computer-use";
protected readonly taskLabel = "claude-computer-use";

/**
* Start a new Claude Computer Use task job
* @param params The parameters for the task job
Expand Down
7 changes: 5 additions & 2 deletions src/services/agents/cua.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { HyperbrowserError } from "../../client";
import { BasicResponse } from "../../types";
import { POLLING_ATTEMPTS } from "../../types/constants";
import { sleep } from "../../utils";
import { BaseService } from "../base";
import { AgentTaskListService } from "./base";
import {
CuaTaskResponse,
CuaTaskStatusResponse,
StartCuaTaskParams,
StartCuaTaskResponse,
} from "../../types/agents/cua";

export class CuaService extends BaseService {
export class CuaService extends AgentTaskListService {
protected readonly taskPath = "cua";
protected readonly taskLabel = "cua";

/**
* Start a new CUA task job
* @param params The parameters for the task job
Expand Down
7 changes: 5 additions & 2 deletions src/services/agents/gemini-computer-use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { HyperbrowserError } from "../../client";
import { BasicResponse } from "../../types";
import { POLLING_ATTEMPTS } from "../../types/constants";
import { sleep } from "../../utils";
import { BaseService } from "../base";
import { AgentTaskListService } from "./base";
import {
GeminiComputerUseTaskResponse,
GeminiComputerUseTaskStatusResponse,
StartGeminiComputerUseTaskParams,
StartGeminiComputerUseTaskResponse,
} from "../../types/agents/gemini-computer-use";

export class GeminiComputerUseService extends BaseService {
export class GeminiComputerUseService extends AgentTaskListService {
protected readonly taskPath = "gemini-computer-use";
protected readonly taskLabel = "gemini-computer-use";

/**
* Start a new Gemini Computer Use task job
* @param params The parameters for the task job
Expand Down
7 changes: 5 additions & 2 deletions src/services/agents/hyper-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ import { HyperbrowserError } from "../../client";
import { BasicResponse } from "../../types";
import { POLLING_ATTEMPTS } from "../../types/constants";
import { sleep } from "../../utils";
import { BaseService } from "../base";
import { AgentTaskListService } from "./base";
import {
HyperAgentTaskResponse,
HyperAgentTaskStatusResponse,
StartHyperAgentTaskParams,
StartHyperAgentTaskResponse,
} from "../../types/agents/hyper-agent";

export class HyperAgentService extends BaseService {
export class HyperAgentService extends AgentTaskListService {
protected readonly taskPath = "hyper-agent";
protected readonly taskLabel = "hyper-agent";

/**
* Start a new HyperAgent task job
* @param params The parameters for the task job
Expand Down
87 changes: 87 additions & 0 deletions src/services/agents/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { HyperbrowserError } from "../../client";
import { BasicResponse } from "../../types";
import { POLLING_ATTEMPTS } from "../../types/constants";
import {
StartTaskParams,
StartTaskResponse,
TaskResponse,
TaskStatusResponse,
} from "../../types/agents/task";
import { sleep } from "../../utils";
import { BaseService } from "../base";

export class TaskService extends BaseService {
async start(params: StartTaskParams): Promise<StartTaskResponse> {
try {
return await this.request<StartTaskResponse>("/task", {
method: "POST",
body: JSON.stringify(params),
});
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError("Failed to start task job", undefined);
}
}

async getStatus(id: string): Promise<TaskStatusResponse> {
try {
return await this.request<TaskStatusResponse>(`/task/${id}/status`);
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError(`Failed to get task job ${id} status`, undefined);
}
}

async get(id: string): Promise<TaskResponse> {
try {
return await this.request<TaskResponse>(`/task/${id}`);
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError(`Failed to get task job ${id}`, undefined);
}
}

async stop(id: string): Promise<BasicResponse> {
try {
return await this.request<BasicResponse>(`/task/${id}/stop`, { method: "PUT" });
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError(`Failed to stop task job ${id}`, undefined);
}
}

async startAndWait(params: StartTaskParams): Promise<TaskResponse> {
const jobStartResp = await this.start(params);
const jobId = jobStartResp.jobId;
if (!jobId) {
throw new HyperbrowserError("Failed to start task job");
}

let failures = 0;
while (true) {
try {
const jobResponse = await this.getStatus(jobId);
if (["completed", "failed", "stopped"].includes(jobResponse.status)) {
return await this.get(jobId);
}
failures = 0;
} catch (error) {
failures++;
if (failures >= POLLING_ATTEMPTS) {
throw new HyperbrowserError(
`Failed to poll task job ${jobId} after ${POLLING_ATTEMPTS} attempts: ${error}`
);
}
}
await sleep(2000);
}
Comment thread
cursor[bot] marked this conversation as resolved.
}
}
40 changes: 40 additions & 0 deletions src/services/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
CreateProfileParams,
ProfileResponse,
CreateProfileResponse,
UpdateProfileParams,
BatchDeleteProfilesParams,
ProfileListParams,
ProfileListResponse,
} from "../types/profile";
Expand Down Expand Up @@ -60,6 +62,44 @@ export class ProfilesService extends BaseService {
}
}


/**
* Update an existing profile
* @param id The ID of the profile to update
* @param params Profile fields to update
*/
async update(id: string, params: UpdateProfileParams): Promise<ProfileResponse> {
try {
return await this.request<ProfileResponse>(`/profile/${id}`, {
method: "PUT",
body: JSON.stringify(params),
});
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError(`Failed to update profile ${id}`, undefined);
}
}

/**
* Delete multiple profiles
* @param params Profile IDs to delete
*/
async deleteMany(params: BatchDeleteProfilesParams): Promise<BasicResponse> {
try {
return await this.request<BasicResponse>("/profiles", {
method: "DELETE",
body: JSON.stringify(params),
});
} catch (error) {
if (error instanceof HyperbrowserError) {
throw error;
}
throw new HyperbrowserError("Failed to delete profiles", undefined);
}
}

/**
* List all profiles with optional pagination
* @param params Optional parameters to filter the profiles
Expand Down
Loading