orgo
Version:
Computers for AI agents
1,021 lines (1,006 loc) • 36.8 kB
JavaScript
'use strict';
var fetch2 = require('cross-fetch');
var uuid = require('uuid');
var Anthropic = require('@anthropic-ai/sdk');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var fetch2__default = /*#__PURE__*/_interopDefault(fetch2);
var Anthropic__default = /*#__PURE__*/_interopDefault(Anthropic);
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// node_modules/tsup/assets/cjs_shims.js
var init_cjs_shims = __esm({
"node_modules/tsup/assets/cjs_shims.js"() {
}
});
// src/utils/auth.ts
function getApiKey(apiKey) {
let envApiKey;
if (typeof process !== "undefined" && process.env) {
envApiKey = process.env.ORGO_API_KEY;
} else if (typeof window !== "undefined" && window.ORGO_API_KEY) {
envApiKey = window.ORGO_API_KEY;
}
const key = apiKey || envApiKey;
if (!key) {
throw new Error(
"API key required. Set ORGO_API_KEY environment variable or pass apiKey parameter. Get a key at https://www.orgo.ai/start"
);
}
return key;
}
var init_auth = __esm({
"src/utils/auth.ts"() {
init_cjs_shims();
}
});
// src/errors.ts
exports.OrgoError = void 0; exports.ApiError = void 0; exports.ConfigError = void 0;
var init_errors = __esm({
"src/errors.ts"() {
init_cjs_shims();
exports.OrgoError = class _OrgoError extends Error {
constructor(message) {
super(message);
this.name = "OrgoError";
Object.setPrototypeOf(this, _OrgoError.prototype);
}
};
exports.ApiError = class _ApiError extends exports.OrgoError {
constructor(message, statusCode, response) {
super(message);
this.name = "ApiError";
this.statusCode = statusCode;
this.response = response;
Object.setPrototypeOf(this, _ApiError.prototype);
}
};
exports.ConfigError = class _ConfigError extends exports.OrgoError {
constructor(message) {
super(message);
this.name = "ConfigError";
Object.setPrototypeOf(this, _ConfigError.prototype);
}
};
}
});
var ApiClient;
var init_client = __esm({
"src/api/client.ts"() {
init_cjs_shims();
init_auth();
init_errors();
ApiClient = class {
constructor(apiKey, baseUrl) {
this.apiKey = getApiKey(apiKey);
this.baseUrl = baseUrl || "https://www.orgo.ai/api";
this.headers = {
"Authorization": `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
"Accept": "application/json"
};
}
async request(method, endpoint, data) {
const url = `${this.baseUrl}/${endpoint}`;
try {
const options = {
method,
headers: this.headers
};
if (method === "GET" && data) {
const params = new URLSearchParams(data);
const urlWithParams = `${url}?${params}`;
const response2 = await fetch2__default.default(urlWithParams, options);
return this.handleResponse(response2);
} else if (data) {
options.body = JSON.stringify(data);
}
const response = await fetch2__default.default(url, options);
return this.handleResponse(response);
} catch (error) {
if (error instanceof exports.ApiError) {
throw error;
}
throw new exports.ApiError(`Connection error: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
async handleResponse(response) {
if (!response.ok) {
let errorMessage = `API error: ${response.status}`;
try {
const errorData = await response.json();
if (errorData.error) {
errorMessage = errorData.error;
}
} catch {
}
throw new exports.ApiError(errorMessage, response.status, response);
}
return response.json();
}
// Project methods
async createProject(name) {
return this.request("POST", "projects", { name });
}
async getProjectByName(name) {
const projects = await this.listProjects();
const project = projects.find((p) => p.name === name);
if (!project) {
throw new exports.ApiError(`Project '${name}' not found`, 404);
}
return project;
}
async getProject(projectId) {
return this.request("GET", `projects/${projectId}`);
}
async listProjects() {
const response = await this.request("GET", "projects");
return response.projects || [];
}
async deleteProject(projectId) {
return this.request("DELETE", `projects/${projectId}`);
}
// Computer methods
async createComputer(projectId, computerName, os = "linux", ram = 2, cpu = 2, gpu = "none") {
return this.request("POST", "computers", {
project_id: projectId,
name: computerName,
os,
ram,
cpu,
gpu
});
}
async listComputers(projectId) {
const project = await this.getProject(projectId);
return project.desktops || [];
}
async getComputer(computerId) {
return this.request("GET", `computers/${computerId}`);
}
async deleteComputer(computerId) {
return this.request("DELETE", `computers/${computerId}`);
}
async restartComputer(computerId) {
return this.request("POST", `computers/${computerId}/restart`);
}
// Computer control methods
async leftClick(computerId, x, y) {
return this.request("POST", `computers/${computerId}/click`, {
button: "left",
x,
y
});
}
async rightClick(computerId, x, y) {
return this.request("POST", `computers/${computerId}/click`, {
button: "right",
x,
y
});
}
async doubleClick(computerId, x, y) {
return this.request("POST", `computers/${computerId}/click`, {
button: "left",
x,
y,
double: true
});
}
async drag(computerId, startX, startY, endX, endY, button = "left", duration = 0.5) {
return this.request("POST", `computers/${computerId}/drag`, {
start_x: startX,
start_y: startY,
end_x: endX,
end_y: endY,
button,
duration
});
}
async scroll(computerId, direction, amount = 3) {
return this.request("POST", `computers/${computerId}/scroll`, {
direction,
amount
});
}
async typeText(computerId, text) {
return this.request("POST", `computers/${computerId}/type`, {
text
});
}
async keyPress(computerId, key) {
return this.request("POST", `computers/${computerId}/key`, {
key
});
}
async getScreenshot(computerId) {
return this.request("GET", `computers/${computerId}/screenshot`);
}
async executeBash(computerId, command) {
return this.request("POST", `computers/${computerId}/bash`, {
command
});
}
async executePython(computerId, code, timeout = 10) {
return this.request("POST", `computers/${computerId}/exec`, {
code,
timeout
});
}
async wait(computerId, seconds) {
return this.request("POST", `computers/${computerId}/wait`, {
duration: seconds
});
}
// Streaming methods
async startStream(computerId, connectionName) {
return this.request("POST", `computers/${computerId}/stream/start`, {
connection_name: connectionName
});
}
async stopStream(computerId) {
return this.request("POST", `computers/${computerId}/stream/stop`);
}
async getStreamStatus(computerId) {
return this.request("GET", `computers/${computerId}/stream/status`);
}
};
}
});
// src/project.ts
var project_exports = {};
__export(project_exports, {
Project: () => exports.Project
});
exports.Project = void 0;
var init_project = __esm({
"src/project.ts"() {
init_cjs_shims();
init_client();
init_auth();
exports.Project = class _Project {
constructor(name, apiKey, baseApiUrl) {
this.name = name;
this.apiKey = apiKey;
this.baseApiUrl = baseApiUrl;
this.api = new ApiClient(this.apiKey, this.baseApiUrl);
}
/**
* Create or connect to a Project
*
* @param options Configuration options
* @param options.name Project name. If exists, connects to it. If not, creates it.
* @param options.apiKey Orgo API key (defaults to ORGO_API_KEY env var)
* @param options.baseApiUrl Custom API URL (optional)
*/
static async create(options) {
const apiKey = options?.apiKey || getApiKey() || "";
const name = options?.name || `project-${uuid.v4().substring(0, 8)}`;
const project = new _Project(name, apiKey, options?.baseApiUrl);
await project._initializeProject();
return project;
}
async _initializeProject() {
try {
const projectInfo = await this.api.getProjectByName(this.name);
this.id = projectInfo.id;
this._info = projectInfo;
} catch (error) {
const projectInfo = await this.api.createProject(this.name);
this.id = projectInfo.id;
this._info = projectInfo;
}
}
get info() {
return this._info;
}
async status() {
const projectInfo = await this.api.getProject(this.id);
this._info = projectInfo;
return projectInfo;
}
async destroy() {
return this.api.deleteProject(this.id);
}
async listComputers() {
return this.api.listComputers(this.id);
}
async getComputer(computerName) {
const computers = await this.listComputers();
if (!computers || computers.length === 0) {
return null;
}
if (computerName) {
const computer = computers.find((c) => c.name === computerName);
return computer ?? null;
}
return computers[0] ?? null;
}
};
}
});
var AnthropicProvider;
var init_anthropic = __esm({
"src/providers/anthropic.ts"() {
init_cjs_shims();
init_client();
AnthropicProvider = class {
constructor() {
try {
this.anthropic = Anthropic__default.default;
} catch (error) {
throw new Error(
"Anthropic SDK not installed. Please install with 'npm install @anthropic-ai/sdk'"
);
}
}
async execute(options) {
const {
computerId,
instruction,
callback,
apiKey = process.env.ANTHROPIC_API_KEY,
model = "claude-3-7-sonnet-20250219",
displayWidth = 1024,
displayHeight = 768,
orgoApiKey,
orgoBaseUrl,
maxSavedScreenshots = 2,
thinkingEnabled = false,
thinkingBudget = 1024,
maxTokens = 4096,
maxIterations = 20
} = options;
if (!apiKey) {
throw new Error(
"No Anthropic API key provided. Set ANTHROPIC_API_KEY environment variable or pass apiKey."
);
}
const client = new this.anthropic({ apiKey });
const messages = [
{ role: "user", content: instruction }
];
const systemPrompt = this.getSystemPrompt(displayWidth, displayHeight);
try {
const tools = [
{
type: "computer_20250124",
name: "computer",
display_width_px: displayWidth,
display_height_px: displayHeight,
display_number: 1
}
];
if (callback) {
callback("status", "Starting conversation with Claude");
}
const apiClient = new ApiClient(orgoApiKey, orgoBaseUrl);
let iteration = 0;
let screenshotCount = 0;
while (iteration < maxIterations) {
iteration++;
if (screenshotCount > maxSavedScreenshots) {
this.filterToNMostRecentImages(messages, maxSavedScreenshots);
screenshotCount = maxSavedScreenshots;
}
const requestParams = {
model,
max_tokens: maxTokens,
system: systemPrompt,
messages,
tools,
betas: ["computer-use-2025-01-24"]
};
if (thinkingEnabled) {
requestParams.thinking = {
type: "enabled",
budget_tokens: thinkingBudget
};
}
try {
const response = await client.beta.messages.create(requestParams);
const responseContent = response.content;
const assistantMessage = {
role: "assistant",
content: responseContent
};
messages.push(assistantMessage);
for (const block of responseContent) {
if (block.type === "text" && callback) {
callback("text", block.text);
} else if (block.type === "thinking" && callback) {
callback("thinking", block.thinking);
} else if (block.type === "tool_use" && callback) {
const toolParams = {
action: block.name.split(".").pop(),
...block.input
};
callback("tool_use", toolParams);
}
}
const toolResults = [];
for (const block of responseContent) {
if (block.type === "tool_use") {
const result = await this.executeTool(
computerId,
block.input,
callback,
apiClient
);
const toolResult = {
type: "tool_result",
tool_use_id: block.id,
content: []
};
if (typeof result === "object" && result !== null && "type" in result && result.type === "image") {
toolResult.content = [result];
if (block.input.action === "screenshot") {
screenshotCount++;
}
} else {
toolResult.content = [{
type: "text",
text: String(result)
}];
}
toolResults.push(toolResult);
}
}
if (toolResults.length === 0) {
if (callback) {
callback("status", "Task completed");
}
return messages;
}
messages.push({
role: "user",
content: toolResults
});
} catch (error) {
if (error instanceof Error && error.message.toLowerCase().includes("base64")) {
if (callback) {
callback("error", "Base64 error detected. Attempting recovery...");
}
this.filterToNMostRecentImages(messages, 1);
continue;
}
throw error;
}
}
if (callback) {
callback("status", `Reached maximum iterations (${maxIterations})`);
}
return messages;
} catch (error) {
if (callback) {
callback("error", error instanceof Error ? error.message : String(error));
}
throw error;
}
}
getSystemPrompt(displayWidth, displayHeight) {
return `You are Claude, an AI assistant that controls a virtual Ubuntu computer with internet access.
<SYSTEM_CAPABILITY>
* You are utilising an Ubuntu virtual machine with a display resolution of ${displayWidth}x${displayHeight}.
* You can take screenshots to see the current state and control the computer by clicking, typing, pressing keys, and scrolling.
* The virtual environment is an Ubuntu system with standard applications.
* Always start by taking a screenshot to see the current state before performing any actions.
</SYSTEM_CAPABILITY>
<UBUNTU_DESKTOP_GUIDELINES>
* CRITICAL INSTRUCTION: When opening applications or files on the Ubuntu desktop, you MUST USE DOUBLE-CLICK rather than single-click.
* Single-click only selects desktop icons but DOES NOT open them. To open desktop icons, you MUST use double-click.
* Common desktop interactions:
- Desktop icons: DOUBLE-CLICK to open applications and folders
- Menu items: SINGLE-CLICK to select options
- Taskbar icons: SINGLE-CLICK to open applications
- Window buttons: SINGLE-CLICK to use close, minimize, maximize buttons
- File browser items: DOUBLE-CLICK to open folders and files
- When submitting, use the 'Enter' key, not the 'Return' key.
* If you see an icon on the desktop that you need to open, ALWAYS use the double_click action, never use left_click.
</UBUNTU_DESKTOP_GUIDELINES>
<SCREENSHOT_GUIDELINES>
* Be mindful of how many screenshots you take - they consume significant memory.
* Only take screenshots when you need to see the current state of the screen.
* Try to batch multiple actions before taking another screenshot.
* For better performance, limit the number of screenshots you take.
</SCREENSHOT_GUIDELINES>`;
}
filterToNMostRecentImages(messages, maxImages) {
const imageBlocks = [];
messages.forEach((msg, msgIdx) => {
if (msg.role !== "user") return;
const content = msg.content;
if (!Array.isArray(content)) return;
content.forEach((block, contentIdx) => {
if (block?.type !== "tool_result") return;
const blockContent = block.content || [];
blockContent.forEach((item, itemIdx) => {
if (item?.type === "image" && item.source) {
imageBlocks.push({
msgIdx,
contentIdx,
contentItemIdx: itemIdx,
contentItem: item
});
}
});
});
});
if (imageBlocks.length > maxImages) {
const toRemove = imageBlocks.slice(0, -maxImages);
toRemove.forEach(({ contentItem }) => {
if (contentItem.source?.data) {
contentItem.source.data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";
contentItem.source.media_type = "image/png";
}
});
}
}
async executeTool(computerId, params, callback, apiClient) {
const action = params.action;
if (callback) {
callback("tool_executing", { action, params });
}
try {
if (!apiClient) {
apiClient = new ApiClient();
}
switch (action) {
case "screenshot": {
const response = await apiClient.getScreenshot(computerId);
if (callback) {
callback("tool_result", { type: "image", action: "screenshot" });
}
const imageUrl = response.image;
if (!imageUrl) {
throw new Error("No image URL received from API");
}
const imgResponse = await fetch(imageUrl);
if (!imgResponse.ok) {
throw new Error(`Failed to fetch image: ${imgResponse.statusText}`);
}
const arrayBuffer = await imgResponse.arrayBuffer();
const base64 = Buffer.from(arrayBuffer).toString("base64");
return {
type: "image",
source: {
type: "base64",
media_type: "image/jpeg",
data: base64
}
};
}
case "left_click": {
const coord = params.coordinate;
if (!coord) {
throw new Error("Coordinates required for left click");
}
const [x, y] = coord;
await apiClient.leftClick(computerId, x, y);
if (callback) {
callback("tool_result", { action: "left_click", x, y });
}
return `Left-clicked at (${x}, ${y})`;
}
case "right_click": {
const coord = params.coordinate;
if (!coord) {
throw new Error("Coordinates required for right click");
}
const [x, y] = coord;
await apiClient.rightClick(computerId, x, y);
if (callback) {
callback("tool_result", { action: "right_click", x, y });
}
return `Right-clicked at (${x}, ${y})`;
}
case "double_click": {
const coord = params.coordinate;
if (!coord) {
throw new Error("Coordinates required for double click");
}
const [x, y] = coord;
await apiClient.doubleClick(computerId, x, y);
if (callback) {
callback("tool_result", { action: "double_click", x, y });
}
return `Double-clicked at (${x}, ${y})`;
}
case "type": {
const text = params.text;
if (!text) {
throw new Error("Text required for typing");
}
await apiClient.typeText(computerId, text);
if (callback) {
callback("tool_result", { action: "type", text });
}
return `Typed: "${text}"`;
}
case "key": {
let key = params.text;
if (!key) {
throw new Error("Key required for key press");
}
if (key.toLowerCase() === "return") {
key = "enter";
}
await apiClient.keyPress(computerId, key);
if (callback) {
callback("tool_result", { action: "key", key });
}
return `Pressed key: ${key}`;
}
case "scroll": {
const direction = params.scroll_direction;
const amount = params.scroll_amount;
if (!direction || amount === void 0) {
throw new Error("Direction and amount required for scrolling");
}
await apiClient.scroll(computerId, direction, amount);
if (callback) {
callback("tool_result", { action: "scroll", direction, amount });
}
return `Scrolled ${direction} by ${amount}`;
}
case "wait": {
const duration = params.duration || 1;
await apiClient.wait(computerId, duration);
if (callback) {
callback("tool_result", { action: "wait", duration });
}
return `Waited for ${duration} second(s)`;
}
default: {
const error = `Unsupported action: ${action}`;
if (callback) {
callback("error", error);
}
throw new Error(error);
}
}
} catch (error) {
const errorMsg = `Error executing ${action}: ${error instanceof Error ? error.message : String(error)}`;
if (callback) {
callback("error", errorMsg);
}
return `Error: ${errorMsg}`;
}
}
};
}
});
// src/prompt.ts
function getProvider(providerName = "anthropic") {
const ProviderClass = PROVIDER_MAPPING[providerName];
if (!ProviderClass) {
const available = Object.keys(PROVIDER_MAPPING).join(", ");
throw new Error(`Unknown provider: ${providerName}. Available providers: ${available}`);
}
return new ProviderClass();
}
var PROVIDER_MAPPING;
var init_prompt = __esm({
"src/prompt.ts"() {
init_cjs_shims();
init_anthropic();
PROVIDER_MAPPING = {
anthropic: AnthropicProvider
// Add more providers here as needed
};
}
});
// src/computer.ts
var computer_exports = {};
__export(computer_exports, {
Computer: () => exports.Computer
});
exports.Computer = void 0;
var init_computer = __esm({
"src/computer.ts"() {
init_cjs_shims();
init_client();
init_project();
init_prompt();
exports.Computer = class _Computer {
constructor(apiKey, baseApiUrl, os = "linux", ram = 2, cpu = 2, gpu = "none") {
this.apiKey = apiKey;
this.baseApiUrl = baseApiUrl;
this.api = new ApiClient(this.apiKey, this.baseApiUrl);
this.os = os;
this.ram = ram;
this.cpu = cpu;
this.gpu = gpu;
}
/**
* Create a new Computer instance
*
* @param options Configuration options
* @param options.project Project name (string) or Project instance. If not provided, creates a new project.
* @param options.name Computer name within the project (optional, auto-generated if not provided)
* @param options.computerId Existing computer ID to connect to (optional)
* @param options.apiKey Orgo API key (defaults to ORGO_API_KEY env var)
* @param options.baseApiUrl Custom API URL (optional)
* @param options.ram RAM in GB (1, 2, 4, 8, 16, 32, or 64) - only used when creating
* @param options.memory Alternative parameter for RAM in GB - only used when creating
* @param options.cpu CPU cores (1, 2, 4, 8, or 16) - only used when creating
* @param options.os Operating system ("linux" or "windows") - only used when creating
* @param options.gpu GPU type - only used when creating
*/
static async create(options) {
let envApiKey = "";
if (typeof process !== "undefined" && process.env && process.env.ORGO_API_KEY) {
envApiKey = process.env.ORGO_API_KEY;
}
const apiKey = options?.apiKey || envApiKey || "";
let ram = options?.ram;
if (ram === void 0 && options?.memory !== void 0) {
ram = options.memory;
}
const computer = new _Computer(
apiKey,
options?.baseApiUrl,
options?.os || "linux",
ram || 2,
options?.cpu || 2,
options?.gpu || "none"
);
if (options?.computerId) {
computer.computerId = options.computerId;
computer.name = options.name;
console.info(`Connected to computer ID: ${computer.computerId}`);
} else if (options?.project) {
if (typeof options.project === "string") {
await computer._initializeWithProjectName(options.project, options?.name);
} else if (options.project instanceof exports.Project) {
await computer._initializeWithProjectInstance(options.project, options?.name);
} else {
throw new Error("project must be a string (project name) or Project instance");
}
} else {
await computer._createNewProjectAndComputer(options?.name);
}
return computer;
}
async _initializeWithProjectName(projectName, computerName) {
this.projectName = projectName;
try {
const project = await this.api.getProjectByName(projectName);
this.projectId = project.id;
const computers = await this.api.listComputers(this.projectId);
if (computerName) {
const existing = computers.find((c) => c.name === computerName);
if (existing) {
await this._connectToExistingComputer(existing);
} else {
await this._createComputer(this.projectId, computerName);
}
} else if (computers.length > 0) {
const firstComputer = computers[0];
if (firstComputer) {
await this._connectToExistingComputer(firstComputer);
} else {
await this._createComputer(this.projectId, computerName);
}
} else {
await this._createComputer(this.projectId, computerName);
}
} catch (error) {
console.info(`Project ${projectName} not found, creating new project`);
const project = await this.api.createProject(projectName);
this.projectId = project.id;
await this._createComputer(this.projectId, computerName);
}
}
async _initializeWithProjectInstance(project, computerName) {
this.projectName = project.name;
this.projectId = project.id;
const computers = await project.listComputers();
if (computerName) {
const existing = computers.find((c) => c.name === computerName);
if (existing) {
await this._connectToExistingComputer(existing);
} else {
await this._createComputer(this.projectId, computerName);
}
} else if (computers.length > 0) {
const firstComputer = computers[0];
if (firstComputer) {
await this._connectToExistingComputer(firstComputer);
} else {
await this._createComputer(this.projectId, computerName);
}
} else {
await this._createComputer(this.projectId, computerName);
}
}
async _createNewProjectAndComputer(computerName) {
const projectName = `project-${uuid.v4().substring(0, 8)}`;
const project = await this.api.createProject(projectName);
this.projectId = project.id;
this.projectName = projectName;
await this._createComputer(this.projectId, computerName);
}
async _connectToExistingComputer(computerInfo) {
this.computerId = computerInfo.id;
this.name = computerInfo.name;
console.info(`Connected to existing computer ${this.name} (ID: ${this.computerId})`);
}
async _createComputer(projectId, computerName) {
if (!computerName) {
computerName = `desktop-${uuid.v4().substring(0, 8)}`;
}
this.name = computerName;
const validRam = [1, 2, 4, 8, 16, 32, 64];
const validCpu = [1, 2, 4, 8, 16];
const validOs = ["linux", "windows"];
const validGpu = ["none", "a10", "l40s", "a100-40gb", "a100-80gb"];
if (!validRam.includes(this.ram)) {
throw new Error(`ram must be one of: ${validRam.join(", ")} GB`);
}
if (!validCpu.includes(this.cpu)) {
throw new Error(`cpu must be one of: ${validCpu.join(", ")} cores`);
}
if (!validOs.includes(this.os)) {
throw new Error(`os must be either 'linux' or 'windows'`);
}
if (!validGpu.includes(this.gpu)) {
throw new Error(`gpu must be one of: ${validGpu.join(", ")}`);
}
const computer = await this.api.createComputer(
projectId,
computerName,
this.os,
this.ram,
this.cpu,
this.gpu
);
this.computerId = computer.id;
console.info(`Created new computer ${this.name} (ID: ${this.computerId})`);
}
async status() {
return this.api.getComputer(this.computerId);
}
async restart() {
return this.api.restartComputer(this.computerId);
}
async destroy() {
return this.api.deleteComputer(this.computerId);
}
// Navigation methods
async leftClick(x, y) {
return this.api.leftClick(this.computerId, x, y);
}
async rightClick(x, y) {
return this.api.rightClick(this.computerId, x, y);
}
async doubleClick(x, y) {
return this.api.doubleClick(this.computerId, x, y);
}
async drag(startX, startY, endX, endY, button = "left", duration = 0.5) {
return this.api.drag(this.computerId, startX, startY, endX, endY, button, duration);
}
async scroll(direction = "down", amount = 3) {
return this.api.scroll(this.computerId, direction, amount);
}
// Input methods
async type(text) {
return this.api.typeText(this.computerId, text);
}
async key(key) {
return this.api.keyPress(this.computerId, key);
}
// View methods
async screenshot(options) {
const response = await this.api.getScreenshot(this.computerId);
const imageData = response.image || "";
if (imageData.startsWith("http://") || imageData.startsWith("https://")) {
const fetch3 = (await import('cross-fetch')).default;
const imgResponse = await fetch3(imageData);
if (!imgResponse.ok) {
throw new Error(`Failed to download screenshot: ${imgResponse.statusText}`);
}
const arrayBuffer = await imgResponse.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
if (options?.format === "base64") {
return buffer.toString("base64");
}
return buffer;
} else {
if (options?.format === "base64") {
return imageData;
}
return Buffer.from(imageData, "base64");
}
}
async screenshotBase64() {
return this.screenshot({ format: "base64" });
}
// Execution methods
async bash(command) {
const response = await this.api.executeBash(this.computerId, command);
return response.output || "";
}
async exec(code, timeout = 10) {
return this.api.executePython(this.computerId, code, timeout);
}
async wait(seconds) {
return this.api.wait(this.computerId, seconds);
}
// Streaming methods
async startStream(connection) {
return this.api.startStream(this.computerId, connection);
}
async stopStream() {
return this.api.stopStream(this.computerId);
}
async streamStatus() {
return this.api.getStreamStatus(this.computerId);
}
// AI control method
async prompt(options) {
const providerInstance = getProvider(options.provider || "anthropic");
return providerInstance.execute({
computerId: this.computerId,
instruction: options.instruction,
callback: options.callback,
apiKey: options.apiKey,
model: options.model || "claude-3-7-sonnet-20250219",
displayWidth: options.displayWidth || 1024,
displayHeight: options.displayHeight || 768,
thinkingEnabled: options.thinkingEnabled || false,
thinkingBudget: options.thinkingBudget || 1024,
maxTokens: options.maxTokens || 4096,
maxIterations: options.maxIterations || 20,
maxSavedScreenshots: options.maxSavedScreenshots || 5,
orgoApiKey: this.apiKey,
orgoBaseUrl: this.baseApiUrl
});
}
};
}
});
// src/index.ts
init_cjs_shims();
init_project();
init_computer();
init_errors();
async function createComputer(options) {
const { Computer: Computer2 } = await Promise.resolve().then(() => (init_computer(), computer_exports));
let computerOptions = {
apiKey: options?.apiKey,
baseApiUrl: options?.baseApiUrl
};
if (options?.projectId) {
computerOptions.project = options.projectId;
}
if (options?.config) {
if ("ram" in options.config) {
computerOptions.ram = options.config.ram;
}
if ("cpu" in options.config) {
computerOptions.cpu = options.config.cpu;
}
if ("os" in options.config) {
computerOptions.os = options.config.os;
}
if ("gpu" in options.config) {
computerOptions.gpu = options.config.gpu;
}
}
return Computer2.create(computerOptions);
}
async function createProject(options) {
const { Project: Project2 } = await Promise.resolve().then(() => (init_project(), project_exports));
return Project2.create(options);
}
exports.createComputer = createComputer;
exports.createProject = createProject;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map