@oagi/oagi 0.1.3 → 0.1.4
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/README.md +7 -7
- package/dist/{chunk-SDBYP57G.js → chunk-JVNTVY6W.js} +28 -17
- package/dist/chunk-JVNTVY6W.js.map +1 -0
- package/dist/cli.cjs +29 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +27 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -6
- package/dist/index.d.ts +13 -6
- package/dist/index.js +1 -1
- package/package.json +5 -6
- package/dist/chunk-SDBYP57G.js.map +0 -1
package/README.md
CHANGED
|
@@ -43,15 +43,15 @@ With Lux, possibilities are endless. Here are a few examples:
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
# If you are using Node.js
|
|
46
|
-
npm install oagi
|
|
47
|
-
yarn add oagi
|
|
48
|
-
pnpm add oagi
|
|
46
|
+
npm install @oagi/oagi
|
|
47
|
+
yarn add @oagi/oagi
|
|
48
|
+
pnpm add @oagi/oagi
|
|
49
49
|
|
|
50
50
|
# If you are using Deno
|
|
51
|
-
deno add npm
|
|
51
|
+
deno add npm:@oagi/oagi
|
|
52
52
|
|
|
53
53
|
# If you are using Bun
|
|
54
|
-
bun install oagi
|
|
54
|
+
bun install @oagi/oagi
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
## Quick Start
|
|
@@ -67,7 +67,7 @@ export OAGI_API_KEY="your-api-key" # get your API key from https://developer.agi
|
|
|
67
67
|
Run tasks automatically with screenshot capture and action execution:
|
|
68
68
|
|
|
69
69
|
```typescript
|
|
70
|
-
import { DefaultActionHandler, DefaultAgent, ScreenshotMaker } from 'oagi';
|
|
70
|
+
import { DefaultActionHandler, DefaultAgent, ScreenshotMaker } from '@oagi/oagi';
|
|
71
71
|
|
|
72
72
|
const agent = new DefaultAgent();
|
|
73
73
|
await agent.execute(
|
|
@@ -128,7 +128,7 @@ const compressed = await sharp('large_screenshot.png')
|
|
|
128
128
|
For step-by-step control over task execution:
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
|
-
import { Actor, DefaultActionHandler, ScreenshotMaker } from 'oagi';
|
|
131
|
+
import { Actor, DefaultActionHandler, ScreenshotMaker } from '@oagi/oagi';
|
|
132
132
|
|
|
133
133
|
const actor = new Actor();
|
|
134
134
|
actor.initTask('Complete the form');
|
|
@@ -366,8 +366,18 @@ ${taskDescription}
|
|
|
366
366
|
// src/client.ts
|
|
367
367
|
var logger2 = logger_default("client");
|
|
368
368
|
var _Client = class _Client {
|
|
369
|
-
|
|
370
|
-
|
|
369
|
+
baseURL;
|
|
370
|
+
apiKey;
|
|
371
|
+
timeout = HTTP_CLIENT_TIMEOUT;
|
|
372
|
+
client;
|
|
373
|
+
constructor(baseURL, apiKey, maxRetries) {
|
|
374
|
+
if (typeof baseURL === "object") {
|
|
375
|
+
({ baseURL, apiKey, maxRetries } = baseURL);
|
|
376
|
+
}
|
|
377
|
+
baseURL ??= process.env.OAGI_BASE_URL ?? DEFAULT_BASE_URL;
|
|
378
|
+
apiKey ??= process.env.OAGI_API_KEY;
|
|
379
|
+
maxRetries ??= DEFAULT_MAX_RETRIES;
|
|
380
|
+
this.baseURL = baseURL;
|
|
371
381
|
this.apiKey = apiKey;
|
|
372
382
|
if (!apiKey) {
|
|
373
383
|
throw new ConfigurationError(
|
|
@@ -375,19 +385,17 @@ var _Client = class _Client {
|
|
|
375
385
|
);
|
|
376
386
|
}
|
|
377
387
|
this.client = new OpenAI({
|
|
378
|
-
baseURL: new URL("./v1",
|
|
388
|
+
baseURL: new URL("./v1", baseURL).href,
|
|
379
389
|
apiKey,
|
|
380
390
|
maxRetries
|
|
381
391
|
});
|
|
382
|
-
logger2.info(`Client initialized with base_url: ${
|
|
392
|
+
logger2.info(`Client initialized with base_url: ${baseURL}`);
|
|
383
393
|
}
|
|
384
|
-
timeout = HTTP_CLIENT_TIMEOUT;
|
|
385
|
-
client;
|
|
386
394
|
fetch(input, init) {
|
|
387
395
|
if (typeof input === "string" || input instanceof URL) {
|
|
388
|
-
input = new URL(input, this.
|
|
396
|
+
input = new URL(input, this.baseURL);
|
|
389
397
|
} else {
|
|
390
|
-
input = new URL(input.url, this.
|
|
398
|
+
input = new URL(input.url, this.baseURL);
|
|
391
399
|
}
|
|
392
400
|
init ??= {};
|
|
393
401
|
const signal = AbortSignal.timeout(this.timeout * 1e3);
|
|
@@ -456,7 +464,10 @@ var _Client = class _Client {
|
|
|
456
464
|
task_id: taskId
|
|
457
465
|
});
|
|
458
466
|
const rawOutput = response.choices[0].message.content ?? "";
|
|
459
|
-
const step =
|
|
467
|
+
const step = {
|
|
468
|
+
...parseRawOutput(rawOutput),
|
|
469
|
+
usage: response.usage
|
|
470
|
+
};
|
|
460
471
|
taskId = response.task_id;
|
|
461
472
|
const task = taskId ? `task_id: ${taskId}, ` : "";
|
|
462
473
|
const usage = response.usage ? `, tokens: ${response.usage.prompt_tokens}+${response.usage.completion_tokens}` : "";
|
|
@@ -611,10 +622,10 @@ var Client = _Client;
|
|
|
611
622
|
import { randomUUID } from "crypto";
|
|
612
623
|
var logger3 = logger_default("task");
|
|
613
624
|
var Actor = class {
|
|
614
|
-
constructor(apiKey,
|
|
625
|
+
constructor(apiKey, baseURL, model = MODEL_ACTOR, temperature) {
|
|
615
626
|
this.model = model;
|
|
616
627
|
this.temperature = temperature;
|
|
617
|
-
this.client = new Client(
|
|
628
|
+
this.client = new Client(baseURL, apiKey);
|
|
618
629
|
}
|
|
619
630
|
/**
|
|
620
631
|
* Client-side generated UUID
|
|
@@ -779,7 +790,7 @@ var DefaultAgent = class {
|
|
|
779
790
|
async execute(instruction, action_handler, image_provider) {
|
|
780
791
|
const actor = new Actor(this.api_key, this.base_url, this.model);
|
|
781
792
|
logger4.info(`Starting async task execution: ${instruction}`);
|
|
782
|
-
|
|
793
|
+
actor.initTask(instruction, this.max_steps);
|
|
783
794
|
resetHandler(action_handler);
|
|
784
795
|
for (let i = 0; i < this.max_steps; i++) {
|
|
785
796
|
const step_num = i + 1;
|
|
@@ -880,7 +891,7 @@ var createAgent = (mode, options = {}) => {
|
|
|
880
891
|
asyncAgentRegister("actor")((options = {}) => {
|
|
881
892
|
const {
|
|
882
893
|
apiKey,
|
|
883
|
-
|
|
894
|
+
baseURL,
|
|
884
895
|
model = MODEL_ACTOR,
|
|
885
896
|
maxSteps = DEFAULT_MAX_STEPS,
|
|
886
897
|
temperature = DEFAULT_TEMPERATURE_LOW,
|
|
@@ -889,7 +900,7 @@ asyncAgentRegister("actor")((options = {}) => {
|
|
|
889
900
|
} = options;
|
|
890
901
|
return new DefaultAgent(
|
|
891
902
|
apiKey,
|
|
892
|
-
|
|
903
|
+
baseURL,
|
|
893
904
|
model,
|
|
894
905
|
maxSteps,
|
|
895
906
|
temperature,
|
|
@@ -900,7 +911,7 @@ asyncAgentRegister("actor")((options = {}) => {
|
|
|
900
911
|
asyncAgentRegister("thinker")((options = {}) => {
|
|
901
912
|
const {
|
|
902
913
|
apiKey,
|
|
903
|
-
|
|
914
|
+
baseURL,
|
|
904
915
|
model = MODEL_THINKER,
|
|
905
916
|
maxSteps = DEFAULT_MAX_STEPS_THINKER,
|
|
906
917
|
temperature = DEFAULT_TEMPERATURE_LOW,
|
|
@@ -909,7 +920,7 @@ asyncAgentRegister("thinker")((options = {}) => {
|
|
|
909
920
|
} = options;
|
|
910
921
|
return new DefaultAgent(
|
|
911
922
|
apiKey,
|
|
912
|
-
|
|
923
|
+
baseURL,
|
|
913
924
|
model,
|
|
914
925
|
maxSteps,
|
|
915
926
|
temperature,
|
|
@@ -1533,4 +1544,4 @@ export {
|
|
|
1533
1544
|
ScreenshotMaker,
|
|
1534
1545
|
DefaultActionHandler
|
|
1535
1546
|
};
|
|
1536
|
-
//# sourceMappingURL=chunk-
|
|
1547
|
+
//# sourceMappingURL=chunk-JVNTVY6W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/consts.ts","../src/logger.ts","../src/types/models/action.ts","../src/types/models/client.ts","../src/types/models/image-config.ts","../src/types/step_observer.ts","../src/utils/output-parser.ts","../src/utils/prompt-builder.ts","../src/actor.ts","../src/agent/default.ts","../src/agent/registry.ts","../src/agent/factories.ts","../src/agent/observer/exporters.ts","../src/agent/observer/agent_observer.ts","../src/handler.ts"],"sourcesContent":["/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nexport class OAGIError extends Error {}\n\nexport class APIError extends OAGIError {\n constructor(\n public response: Response,\n message?: string,\n ) {\n super(message ?? response.statusText);\n }\n\n toString() {\n return `API Error [${this.response.status}]: ${this.message}`;\n }\n}\nexport class AuthenticationError extends APIError {}\nexport class RateLimitError extends APIError {}\nexport class ValidationError extends APIError {}\nexport class NotFoundError extends APIError {}\nexport class ServerError extends APIError {}\n\nexport class ConfigurationError extends OAGIError {}\n\nexport class NetworkError extends OAGIError {\n constructor(\n message: string,\n public originalError: Error,\n ) {\n super(message);\n }\n}\nexport class RequestTimeoutError extends NetworkError {}\n\nexport class RequestError extends OAGIError {\n constructor(public response: Response) {\n super(`${response.status} ${response.statusText}`);\n }\n}\n\nexport class ValueError extends OAGIError {}\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport OpenAI from 'openai';\nimport {\n API_KEY_HELP_URL,\n API_V1_FILE_UPLOAD_ENDPOINT,\n API_V1_GENERATE_ENDPOINT,\n DEFAULT_BASE_URL,\n DEFAULT_MAX_RETRIES,\n HTTP_CLIENT_TIMEOUT,\n} from './consts.js';\nimport {\n APIError,\n AuthenticationError,\n ConfigurationError,\n NetworkError,\n NotFoundError,\n RateLimitError,\n RequestTimeoutError,\n ServerError,\n ValidationError,\n ValueError,\n} from './errors.js';\nimport getLogger, { logTraceOnFailure } from './logger.js';\nimport {\n GenerateResponseSchema,\n UploadFileResponseSchema,\n} from './types/index.js';\nimport type {\n ChatCompletionMessageParam,\n CompletionUsage,\n} from 'openai/resources.js';\nimport type {\n ErrorResponse,\n GenerateOption,\n GenerateResponse,\n Step,\n UploadFileResponse,\n} from './types';\nimport { parseRawOutput } from './utils/index.js';\n\nconst logger = getLogger('client');\n\nexport interface ClientOptions {\n baseURL?: string;\n apiKey?: string;\n maxRetries?: number;\n}\n\n/**\n * HTTP client for the OAGI API.\n */\nexport default class Client {\n private baseURL: string;\n private apiKey?: string;\n private timeout = HTTP_CLIENT_TIMEOUT;\n private client: OpenAI;\n\n constructor(options: ClientOptions);\n constructor(baseURL?: string, apiKey?: string, maxRetries?: number);\n constructor(\n baseURL?: ClientOptions | string,\n apiKey?: string,\n maxRetries?: number,\n ) {\n if (typeof baseURL === 'object') {\n ({ baseURL, apiKey, maxRetries } = baseURL);\n }\n baseURL ??= process.env.OAGI_BASE_URL ?? DEFAULT_BASE_URL;\n apiKey ??= process.env.OAGI_API_KEY;\n maxRetries ??= DEFAULT_MAX_RETRIES;\n\n this.baseURL = baseURL;\n this.apiKey = apiKey;\n if (!apiKey) {\n throw new ConfigurationError(\n `OAGI API key must be provided either as 'api_key' parameter or OAGI_API_KEY environment variable. Get your API key at ${API_KEY_HELP_URL}`,\n );\n }\n this.client = new OpenAI({\n baseURL: new URL('./v1', baseURL).href,\n apiKey,\n maxRetries,\n });\n logger.info(`Client initialized with base_url: ${baseURL}`);\n }\n\n private fetch(\n input: string | URL | Request,\n init?: RequestInit,\n ): Promise<Response> {\n if (typeof input === 'string' || input instanceof URL) {\n input = new URL(input, this.baseURL);\n } else {\n input = new URL(input.url, this.baseURL);\n }\n init ??= {};\n const signal = AbortSignal.timeout(this.timeout * 1000);\n init.signal = init.signal ? AbortSignal.any([signal, init.signal]) : signal;\n return fetch(input, init);\n }\n\n private buildHeaders(apiVersion?: string) {\n const headers: Record<string, string> = {};\n if (apiVersion) {\n headers['x-api-version'] = apiVersion;\n }\n if (this.apiKey) {\n headers['x-api-key'] = this.apiKey;\n }\n return headers;\n }\n\n private async handleResponseError(response: Response): Promise<never> {\n const data = (await response.json()) as ErrorResponse;\n const cls = Client.getErrorClass(response.status);\n const err = new cls(response, data.error?.message);\n logger.error(err.toString());\n throw err;\n }\n\n private handleHttpErrors(err: unknown): never {\n if (err instanceof DOMException) {\n if (err.name === 'TimeoutError') {\n const message = `Request timed out after ${this.timeout} seconds`;\n logger.error(message);\n throw new RequestTimeoutError(message, err);\n }\n } else if (err instanceof TypeError) {\n const message = `Network error: ${err}`;\n logger.error(message);\n throw new NetworkError(message, err);\n }\n throw err;\n }\n\n private static getErrorClass(statusCode: number) {\n if (statusCode >= 500) return ServerError;\n return (\n {\n 401: AuthenticationError,\n 404: NotFoundError,\n 422: ValidationError,\n 429: RateLimitError,\n }[statusCode] ?? APIError\n );\n }\n\n /**\n * Call OpenAI-compatible /v1/chat/completions endpoint.\n *\n * @param model Model to use for inference\n * @param messages Full message history (OpenAI-compatible format)\n * @param temperature Sampling temperature (0.0-2.0)\n * @param taskId Optional task ID for multi-turn conversations\n * @returns Tuple of (Step, raw_output, Usage)\n * - Step: Parsed actions and reasoning\n * - raw_output: Raw model output string (for message history)\n * - Usage: Token usage statistics (or None if not available)\n */\n async chatCompletions(\n model: string,\n messages: ChatCompletionMessageParam[],\n temperature?: number,\n taskId?: string,\n ): Promise<[Step, rawOutput: string, CompletionUsage | undefined]> {\n logger.info(`Making async chat completion request with model: ${model}`);\n const response = await this.client.chat.completions.create({\n model,\n messages,\n temperature,\n // @ts-expect-error extra body\n task_id: taskId,\n });\n const rawOutput = response.choices[0].message.content ?? '';\n const step = {\n ...parseRawOutput(rawOutput),\n usage: response.usage,\n };\n\n // @ts-expect-error Extract task_id from response (custom field from OAGI API)\n taskId = response.task_id;\n const task = taskId ? `task_id: ${taskId}, ` : '';\n const usage = response.usage\n ? `, tokens: ${response.usage.prompt_tokens}+${response.usage.completion_tokens}`\n : '';\n logger.info(\n `Chat completion successful - ${task}actions: ${step.actions.length}, stop: ${step.stop}${usage}`,\n );\n\n return [step, rawOutput, response.usage];\n }\n\n /**\n * Call the /v1/file/upload endpoint to get a S3 presigned URL\n *\n * @param apiVersion API version header\n * @returns {Promise<UploadFileResponse>} The response from /v1/file/upload with uuid and presigned S3 URL\n */\n async getS3PresignedUrl(apiVersion?: string): Promise<UploadFileResponse> {\n logger.debug(`Making async API request to ${API_V1_FILE_UPLOAD_ENDPOINT}`);\n try {\n const headers = this.buildHeaders(apiVersion);\n const response = await this.fetch(API_V1_FILE_UPLOAD_ENDPOINT, {\n headers,\n });\n if (!response.ok) {\n await this.handleResponseError(response);\n }\n try {\n const uploadFileResponse = UploadFileResponseSchema.parse(\n await response.json(),\n );\n logger.debug('Calling /v1/file/upload successful');\n return uploadFileResponse;\n } catch (err) {\n logger.error(`Invalid upload response: ${response.status}`);\n throw new APIError(\n response,\n `Invalid presigned S3 URL response: ${err}`,\n );\n }\n } catch (err) {\n this.handleHttpErrors(err);\n }\n }\n\n /**\n * Upload image bytes to S3 using presigned URL\n *\n * @param url S3 presigned URL\n * @param content Image bytes to upload\n * @throws {APIError} If upload fails\n */\n async uploadToS3(url: string, content: ArrayBuffer) {\n logger.debug('Uploading image to S3');\n let response: Response | null = null;\n try {\n response = await this.fetch(url, {\n body: content,\n method: 'PUT',\n });\n if (!response.ok) {\n await this.handleResponseError(response);\n }\n } catch (err) {\n logger.error(`S3 upload failed ${err}`);\n if (err instanceof APIError) {\n throw err;\n }\n throw new APIError(\n response ?? new Response(null, { status: 500 }),\n `${err}`,\n );\n }\n }\n\n /**\n * Get S3 presigned URL and upload image (convenience method)\n *\n * @param screenshot Screenshot image bytes\n * @param apiVersion API version header\n * @returns {UploadFileResponse} The response from /v1/file/upload with uuid and presigned S3 URL\n */\n async putS3PresignedUrl(screenshot: ArrayBuffer, apiVersion?: string) {\n const uploadFileResponse = await this.getS3PresignedUrl(apiVersion);\n await this.uploadToS3(uploadFileResponse.url, screenshot);\n return uploadFileResponse;\n }\n\n /**\n * Call the /v1/generate endpoint for OAGI worker processing.\n *\n * @returns {Promise<GenerateResponse>} The response from the API\n * @throws {ValueError} If workerId is invalid\n * @throws {APIError} If API returns error\n */\n @logTraceOnFailure\n async callWorker({\n workerId,\n overallTodo,\n taskDescription,\n todos,\n history = [],\n currentTodoIndex,\n taskExecutionSummary,\n currentScreenshot,\n currentSubtaskInstruction,\n windowSteps,\n windowScreenshots,\n resultScreenshot,\n priorNotes,\n latestTodoSummary,\n apiVersion,\n }: GenerateOption): Promise<GenerateResponse> {\n // Validate worker_id\n const validWorkers = ['oagi_first', 'oagi_follow', 'oagi_task_summary'];\n if (!validWorkers.includes(workerId)) {\n throw new ValueError(\n `Invalid worker_id '${workerId}'. Must be one of: ${validWorkers}`,\n );\n }\n logger.info(`Calling /v1/generate with worker_id: ${workerId}`);\n\n // Build flattened payload (no oagi_data wrapper)\n const payload = {\n external_worker_id: workerId,\n overall_todo: overallTodo,\n task_description: taskDescription,\n todos,\n history,\n // Add optional memory fields\n current_todo_index: currentTodoIndex,\n task_execution_summary: taskExecutionSummary,\n // Add optional screenshot/worker-specific fields\n current_screenshot: currentScreenshot,\n current_subtask_instruction: currentSubtaskInstruction,\n window_steps: windowSteps,\n window_screenshots: windowScreenshots,\n result_screenshot: resultScreenshot,\n prior_notes: priorNotes,\n latest_todo_summary: latestTodoSummary,\n };\n\n // # Build headers\n const headers = this.buildHeaders(apiVersion);\n\n // Make request\n try {\n const response = await this.fetch(API_V1_GENERATE_ENDPOINT, {\n body: JSON.stringify(payload),\n headers,\n method: 'POST',\n });\n if (!response.ok) {\n await this.handleResponseError(response);\n }\n const result = GenerateResponseSchema.parse(await response.json());\n // Capture request_id from response header\n result.request_id = response.headers.get('X-Request-ID');\n logger.info(\n `Generate request successful - tokens: ${result.prompt_tokens}+${result.completion_tokens}, request_id: ${result.request_id}`,\n );\n return result;\n } catch (err) {\n this.handleHttpErrors(err);\n }\n }\n}\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\n// URLs & API Endpoints\nexport const DEFAULT_BASE_URL = 'https://api.agiopen.org';\nexport const API_KEY_HELP_URL = 'https://developer.agiopen.org/api-keys';\nexport const API_V1_FILE_UPLOAD_ENDPOINT = '/v1/file/upload';\nexport const API_V1_GENERATE_ENDPOINT = '/v1/generate';\n\n// Model identifiers\nexport const MODEL_ACTOR = 'lux-actor-1';\nexport const MODEL_THINKER = 'lux-thinker-1';\n\n// Agent modes\nexport const MODE_ACTOR = 'actor';\nexport const MODE_THINKER = 'thinker';\nexport const MODE_TASKER = 'tasker';\n\n// Default max steps per model\nexport const DEFAULT_MAX_STEPS = 20;\nexport const DEFAULT_MAX_STEPS_THINKER = 100;\nexport const DEFAULT_MAX_STEPS_TASKER = 60;\n\n// Maximum allowed steps per model (hard limits)\nexport const MAX_STEPS_ACTOR = 30;\nexport const MAX_STEPS_THINKER = 120;\n\n// Reflection intervals\nexport const DEFAULT_REFLECTION_INTERVAL = 4;\nexport const DEFAULT_REFLECTION_INTERVAL_TASKER = 20;\n\n// Timing & Delays\nexport const DEFAULT_STEP_DELAY = 0.3;\n\n// Temperature Defaults\nexport const DEFAULT_TEMPERATURE = 0.5;\nexport const DEFAULT_TEMPERATURE_LOW = 0.1;\n\n// Timeout Values\nexport const HTTP_CLIENT_TIMEOUT = 60;\n\n// Retry Configuration\nexport const DEFAULT_MAX_RETRIES = 2;\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport pino from 'pino';\nimport { APIError } from './errors.js';\n\nconst levelEnv = process.env.OAGI_LOG?.toLowerCase() ?? 'info';\nconst allowedLevels = ['debug', 'info', 'warn', 'error', 'fatal'];\n\nconst logger = pino({\n level: allowedLevels.includes(levelEnv) ? levelEnv : 'info',\n base: null,\n timestamp: () => `,\"time\":\"${new Date().toISOString()}\"`,\n messageKey: 'msg',\n transport: {\n target: 'pino-pretty',\n options: {\n colorize: false,\n translateTime: 'SYS:yyyy-mm-dd HH:MM:ss',\n messageFormat: '{msg}',\n ignore: 'pid,hostname',\n },\n },\n});\n\n/**\n * Get a logger with the specified name under the 'oagi' namespace.\n *\n * Log level is controlled by OAGI_LOG environment variable.\n * Valid values: DEBUG, INFO, WARNING, ERROR, CRITICAL\n * Default: INFO\n */\nconst getLogger = (name: string) => logger.child({ name: `oagi.${name}` });\nexport default getLogger;\n\nexport const logTraceOnFailure = (\n _: unknown,\n __: string,\n descriptor: PropertyDescriptor,\n) => {\n const original = descriptor.value;\n descriptor.value = async function (...args: unknown[]) {\n try {\n return await original.apply(this, args);\n } catch (err) {\n if (err instanceof APIError) {\n const requestId = err.response.headers.get('x-request-id') ?? '';\n const traceId = err.response.headers.get('x-trace-id') ?? '';\n\n logger.error(`Request Id: ${requestId}`);\n logger.error(`Trace Id: ${traceId}`);\n }\n throw err;\n }\n };\n return descriptor;\n};\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport * as z from 'zod';\n\nexport const ActionTypeSchema = z.enum([\n 'click',\n 'left_double',\n 'left_triple',\n 'right_single',\n 'drag',\n 'hotkey',\n 'type',\n 'scroll',\n 'finish',\n 'wait',\n 'call_user',\n]);\nexport type ActionType = z.infer<typeof ActionTypeSchema>;\n\nexport const ActionSchema = z.object({\n /**\n * Type of action to perform\n */\n type: ActionTypeSchema,\n /**\n * Action argument in the specified format\n */\n argument: z.string(),\n /**\n * Number of times to repeat the action\n */\n count: z.int().default(1),\n});\nexport type Action = z.infer<typeof ActionSchema>;\n\n/**\n * Extract x, y coordinates from argument string.\n *\n * @param args Argument string in format \"x, y\" (normalized 0-1000 range)\n * @returns Tuple of (x, y) coordinates, or None if parsing fails\n */\nexport const parseCoords = (args: string): [number, number] | null => {\n const match = /(\\d+),\\s*(\\d+)/.exec(args);\n if (!match) {\n return null;\n }\n return [Number(match[1]), Number(match[2])];\n};\n\n/**\n * Extract x1, y1, x2, y2 coordinates from drag argument string.\n * @param args Argument string in format \"x1, y1, x2, y2\" (normalized 0-1000 range)\n * @returns Tuple of (x1, y1, x2, y2) coordinates, or None if parsing fails\n */\nexport const parseDragCoords = (\n args: string,\n): [number, number, number, number] | null => {\n const match = /(\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)/.exec(args);\n if (!match) {\n return null;\n }\n return [\n Number(match[1]),\n Number(match[2]),\n Number(match[3]),\n Number(match[4]),\n ];\n};\n\n/**\n * Extract x, y, direction from scroll argument string.\n * @param args Argument string in format \"x, y, direction\" (normalized 0-1000 range)\n * @returns Tuple of (x, y, direction) where direction is \"up\" or \"down\", or None if parsing fails\n */\nexport const parseScroll = (args: string): [number, number, string] | null => {\n const match = /(\\d+),\\s*(\\d+),\\s*(\\w+)/.exec(args);\n if (!match) {\n return null;\n }\n return [Number(match[1]), Number(match[2]), match[3].toLowerCase()];\n};\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport * as z from 'zod';\nimport type { Step } from './step';\n\nexport const UsageSchema = z.object({\n prompt_tokens: z.int(),\n completion_tokens: z.int(),\n total_tokens: z.int(),\n});\nexport type Usage = z.infer<typeof UsageSchema>;\n\n/**\n * A single todo item in the task workflow.\n */\nexport interface Todo {\n /**\n * Todo index in the list\n */\n index: number;\n /**\n * Todo description\n */\n description: string;\n /**\n * Current status of the todo\n */\n status: 'pending' | 'in_progress' | 'completed' | 'blocked';\n /**\n * Summary of execution for this todo\n */\n execution_summary?: string;\n}\n\nexport interface HistoryItem {\n /**\n * Index of the todo that was executed\n */\n todo_index: number;\n /**\n * Description of the todo\n */\n todo_description: string;\n /**\n * Number of actions taken\n */\n action_count: number;\n /**\n * Execution summary\n */\n summary?: string;\n /**\n * Whether the todo was completed\n */\n completed: boolean;\n}\n\nexport interface GenerateOption {\n /**\n * One of \"oagi_first\", \"oagi_follow\", \"oagi_task_summary\"\n */\n workerId: string;\n /**\n * Current todo description\n */\n overallTodo: string;\n /**\n * Overall task description\n */\n taskDescription?: string;\n /**\n * List of todo dicts with index, description, status, execution_summary\n */\n todos: Todo[];\n /**\n * List of history dicts with todo_index, todo_description, action_count, summary, completed\n */\n history?: HistoryItem[];\n /**\n * Index of current todo being executed\n */\n currentTodoIndex?: number;\n /**\n * Summary of overall task execution\n */\n taskExecutionSummary?: string;\n /**\n * Uploaded file UUID for screenshot (oagi_first)\n */\n currentScreenshot?: string;\n /**\n * Subtask instruction (oagi_follow)\n */\n currentSubtaskInstruction?: string;\n /**\n * Action steps list (oagi_follow)\n */\n windowSteps?: Step[];\n /**\n * Uploaded file UUIDs list (oagi_follow)\n */\n windowScreenshots?: string[];\n /**\n * Uploaded file UUID for result screenshot (oagi_follow)\n */\n resultScreenshot?: string;\n /**\n * Execution notes (oagi_follow)\n */\n priorNotes?: string;\n /**\n * Latest summary (oagi_task_summary)\n */\n latestTodoSummary?: string;\n /**\n * API version header\n */\n apiVersion?: string;\n}\n\nexport const ErrorDetailSchema = z.object({\n code: z.string(),\n message: z.string(),\n});\n/**\n * Detailed error information.\n */\nexport type ErrorDetail = z.infer<typeof ErrorDetailSchema>;\n\nexport const ErrorResponseSchema = z.object({\n error: ErrorDetailSchema.nullish(),\n});\n/**\n * Standard error response format.\n */\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\nexport const UploadFileResponseSchema = z.object({\n url: z.string(),\n uuid: z.string(),\n expires_at: z.int(),\n file_expires_at: z.int(),\n download_url: z.string(),\n});\n/**\n * Response from S3 presigned URL upload.\n */\nexport type UploadFileResponse = z.infer<typeof UploadFileResponseSchema>;\n\nexport const GenerateResponseSchema = z.object({\n response: z.string(),\n prompt_tokens: z.int(),\n completion_tokens: z.int(),\n /**\n * @deprecated This field is deprecated\n */\n cost: z.float64().nullish(),\n request_id: z.string().nullish(),\n});\n/**\n * Response from /v1/generate endpoint.\n */\nexport type GenerateResponse = z.infer<typeof GenerateResponseSchema>;\n","import * as z from 'zod';\n\nexport const ImageConfigSchema = z\n .object({\n format: z.enum(['PNG', 'JPEG']).default('JPEG'),\n quality: z.int().min(1).max(100).default(85),\n width: z.int().positive().nullish().default(1260),\n height: z.int().positive().nullish().default(700),\n optimize: z.boolean().default(false),\n resample: z\n .enum(['NEAREST', 'BILINEAR', 'BICUBIC', 'LANCZOS'])\n .default('LANCZOS'),\n })\n .transform(value => {\n if (value.format === 'PNG') {\n return { ...value, quality: 85 };\n }\n return value;\n });\n\nexport type ImageConfig = z.infer<typeof ImageConfigSchema>;\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport * as z from 'zod';\nimport { Step } from './models/step.js';\nimport { Action } from './models/action.js';\n\nexport const BaseEventSchema = z.object({\n timestamp: z.date().default(() => new Date()),\n});\n\nexport type BaseEvent = z.infer<typeof BaseEventSchema>;\n\nexport const ImageEventSchema = BaseEventSchema.extend({\n type: z.literal('image'),\n step_num: z.number(),\n image: z.string(),\n});\n\nexport type ImageEvent = z.infer<typeof ImageEventSchema>;\n\nexport const StepEventSchema = BaseEventSchema.extend({\n type: z.literal('step'),\n step_num: z.number(),\n image: z.custom<ArrayBuffer>(),\n step: z.custom<Step>(),\n task_id: z.string().optional(),\n});\n\nexport type StepEvent = z.infer<typeof StepEventSchema>;\n\nexport const ActionEventSchema = BaseEventSchema.extend({\n type: z.literal('action'),\n step_num: z.number(),\n actions: z.array(z.custom<Action>()),\n error: z.string().optional(),\n});\n\nexport type ActionEvent = z.infer<typeof ActionEventSchema>;\n\nexport const LogEventSchema = BaseEventSchema.extend({\n type: z.literal('log'),\n message: z.string(),\n});\n\nexport type LogEvent = z.infer<typeof LogEventSchema>;\n\nexport const SplitEventSchema = BaseEventSchema.extend({\n type: z.literal('split'),\n label: z.string().optional(),\n});\n\nexport type SplitEvent = z.infer<typeof SplitEventSchema>;\n\nexport const PlanEventSchema = BaseEventSchema.extend({\n type: z.literal('plan'),\n phase: z.enum(['initial', 'reflection', 'summary']),\n image: z.string().or(z.custom<ArrayBuffer>()).optional(),\n reasoning: z.string(),\n result: z.string().optional(),\n request_id: z.string().optional(),\n});\n\nexport type PlanEvent = z.infer<typeof PlanEventSchema>;\n\nexport type ObserverEvent =\n | ImageEvent\n | StepEvent\n | ActionEvent\n | LogEvent\n | SplitEvent\n | PlanEvent;\n\nexport abstract class StepObserver {\n abstract onEvent(event: ObserverEvent): Promise<void>;\n\n chain(observer?: StepObserver | null): StepObserver {\n return new ChainedStepObserver([this, observer ?? null]);\n }\n}\n\nexport class ChainedStepObserver extends StepObserver {\n private observers: (StepObserver | null)[];\n constructor(observers: (StepObserver | null)[]) {\n super();\n this.observers = observers;\n }\n\n async onEvent(event: ObserverEvent): Promise<void> {\n return await this.observers.reduce(async (prev, observer) => {\n await prev;\n if (observer) await observer.onEvent(event);\n }, Promise.resolve());\n }\n}\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport { ActionTypeSchema } from '../types/index.js';\nimport type { Action, Step } from '../types';\n\n/**\n * Split action block by & separator, but only when & is outside parentheses.\n *\n * Note: This parser does NOT handle '&' inside quoted strings.\n * E.g., type(\"a&b\") would incorrectly split. The LLM should avoid\n * this pattern by using alternative escape sequences.\n *\n * @param actionBlock String containing one or more actions separated by &\n * @returns List of individual action strings\n */\nconst splitActions = (actionBlock: string): string[] => {\n const actions: string[] = [];\n let currentAction: string[] = [];\n let parenLevel = 0;\n\n for (const char of actionBlock) {\n currentAction.push(char);\n switch (char) {\n case '(':\n parenLevel++;\n break;\n case ')':\n parenLevel--;\n break;\n case '&':\n if (parenLevel === 0) {\n const action = currentAction.join('').trim();\n action && actions.push(action);\n currentAction = [];\n }\n break;\n }\n }\n const lastAction = currentAction.join('').trim();\n lastAction && actions.push(lastAction);\n return actions;\n};\n\n/**\n * Parse individual action text into Action object.\n *\n * Expected formats:\n * - click(x, y) # left-click at position\n * - left_double(x, y) # left-double-click at position\n * - left_triple(x, y) # left-triple-click at position\n * - right_single(x, y) # right-click at position\n * - drag(x1, y1, x2, y2) # drag from (x1, y1) to (x2, y2)\n * - hotkey(key, c) # press key c times\n * - type(text) # type text string\n * - scroll(x, y, direction, c) # scroll at position\n * - wait() # wait for a while\n * - finish() # indicate task is finished\n *\n * @param action String representation of a single action\n * @returns Action object or None if parsing fails\n */\nconst parseAction = (action: string): Action | null => {\n const match = /(\\w+)\\((.*)\\)/.exec(action);\n if (!match) return null;\n\n const { data: actionType, success } = ActionTypeSchema.safeParse(match[1]);\n if (!success) return null;\n\n let argument = match[2].trim();\n const args = argument.split(',');\n let count = 1;\n // Parse specific action types and extract count where applicable\n switch (actionType) {\n // hotkey(key, c) - press key c times\n case 'hotkey':\n if (args.length >= 2 && args[1].trim()) {\n argument = args[0].trim();\n count = Number(args[1].trim());\n }\n break;\n case 'scroll':\n // scroll(x, y, direction, c) - scroll at position\n if (args.length >= 4) {\n const x = args[0].trim();\n const y = args[1].trim();\n const direction = args[2].trim();\n argument = `${x},${y},${direction}`;\n count = Number(args[3].trim());\n }\n break;\n default:\n // For other actions, use default count of 1\n }\n if (!Number.isInteger(count) || count <= 0) {\n count = 1;\n }\n return { type: actionType, argument, count };\n};\n\n/**\n * Parse raw LLM output into structured Step format.\n *\n * Expected format:\n * <|think_start|> reasoning text <|think_end|>\n * <|action_start|> action1(args) & action2(args) & ... <|action_end|>\n *\n * @param rawOutput Raw text output from the LLM\n * @returns Step object with parsed reasoning and actions\n */\nexport const parseRawOutput = (rawOutput: string): Step => {\n const reason =\n /<\\|think_start\\|>(.*?)<\\|think_end\\|>/s.exec(rawOutput)?.[1] ?? '';\n const action =\n /<\\|action_start\\|>(.*?)<\\|action_end\\|>/s.exec(rawOutput)?.[1] ?? '';\n\n const actions = splitActions(action)\n .map(parseAction)\n .filter((action): action is Action => !!action);\n return {\n reason,\n actions,\n stop: actions.some(action => action.type === 'finish'),\n };\n};\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\n/**\n * Build the instruction prompt for the OAGI model.\n *\n * @param taskDescription The task description to include in the prompt\n * @returns The formatted prompt string with action format documentation\n */\nexport const buildPrompt = (\n taskDescription: string,\n) => `You are a Desktop Agent completing computer use tasks from a user instruction.\n\nEvery step, you will look at the screenshot and output the desired actions in a format as:\n\n<|think_start|> brief description of your intent and reasoning <|think_end|>\n<|action_start|> one of the allowed actions as below <|action_end|>\n\nIn the action field, you have the following action formats:\n1. click(x, y) # left-click at the position (x, y), where x and y are integers normalized between 0 and 1000\n2. left_double(x, y) # left-double-click at the position (x, y), where x and y are integers normalized between 0 and 1000\n3. left_triple(x, y) # left-triple-click at the position (x, y), where x and y are integers normalized between 0 and 1000\n4. right_single(x, y) # right-click at the position (x, y), where x and y are integers normalized between 0 and 1000\n5. drag(x1, y1, x2, y2) # drag the mouse from (x1, y1) to (x2, y2) to select or move contents, where x1, y1, x2, y2 are integers normalized between 0 and 1000\n6. hotkey(key, c) # press the key for c times\n7. type(text) # type a text string on the keyboard\n8. scroll(x, y, direction, c) # scroll the mouse at position (x, y) in the direction of up or down for c times, where x and y are integers normalized between 0 and 1000\n9. wait() # wait for a while\n10. finish() # indicate the task is finished\n\nDirectly output the text beginning with <|think_start|>, no additional text is needed for this scenario.\n\nThe user instruction is:\n${taskDescription}\n`;\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport { randomUUID } from 'crypto';\nimport Client from './client.js';\nimport {\n DEFAULT_MAX_STEPS,\n MAX_STEPS_ACTOR,\n MAX_STEPS_THINKER,\n MODEL_ACTOR,\n MODEL_THINKER,\n} from './consts.js';\nimport { ValueError } from './errors.js';\nimport getLogger from './logger.js';\nimport { buildPrompt } from './utils/index.js';\nimport type {\n ChatCompletionContentPart,\n ChatCompletionMessageParam,\n} from 'openai/resources.js';\nimport type { Step } from './types/index.js';\n\nconst logger = getLogger('task');\n\n/**\n * Base class for task automation with the OAGI API.\n */\nexport default class Actor {\n /**\n * Client-side generated UUID\n */\n private taskId = randomUUID();\n private taskDescription: string | null = null;\n /**\n * OpenAI-compatible message history\n */\n private messageHistory: ChatCompletionMessageParam[] = [];\n private maxSteps = DEFAULT_MAX_STEPS;\n /**\n * Current step counter\n */\n private currentStep = 0;\n private client: Client;\n\n constructor(\n apiKey?: string,\n baseURL?: string,\n private model = MODEL_ACTOR,\n private temperature?: number,\n ) {\n this.client = new Client(baseURL, apiKey);\n }\n\n private validateAndIncrementStep() {\n if (!this.taskDescription) {\n throw new ValueError(\n 'Task description must be set. Call initTask() first.',\n );\n }\n if (this.currentStep >= this.maxSteps) {\n throw new ValueError(\n `Max steps limit (${this.maxSteps}) reached. Call initTask() to start a new task.`,\n );\n }\n this.currentStep++;\n }\n\n /**\n * Get screenshot URL, uploading to S3 if needed (async version).\n * @param screenshot Screenshot as URL string, or raw bytes\n * @returns Screenshot URL (either direct or from S3 upload)\n */\n private async ensureScreenshotUrl(screenshot: string | ArrayBuffer) {\n if (typeof screenshot === 'string') return screenshot;\n const uploadResponse = await this.client.putS3PresignedUrl(screenshot);\n return uploadResponse.download_url;\n }\n\n /**\n * Add user message with screenshot to message history.\n *\n * @param screenshot URL of the screenshot\n * @param prompt Optional prompt text (for first message only)\n */\n private addUserMessageToHistory(screenshot: string, prompt?: string) {\n const content: ChatCompletionContentPart[] = [];\n if (prompt) {\n content.push({\n type: 'text',\n text: prompt,\n });\n }\n content.push({\n type: 'image_url',\n image_url: {\n url: screenshot,\n },\n });\n this.messageHistory.push({ role: 'user', content });\n }\n\n /**\n * Build prompt for first message only.\n */\n private buildStepPrompt() {\n if (this.messageHistory.length === 0) {\n return buildPrompt(this.taskDescription!);\n }\n }\n\n /**\n * Initialize a new task with the given description.\n *\n * @param taskDescription Task description\n * @param maxSteps Maximum number of steps allowed\n */\n initTask(taskDescription: string, maxSteps: number = DEFAULT_MAX_STEPS) {\n this.taskId = randomUUID();\n this.taskDescription = taskDescription;\n this.messageHistory = [];\n const limit =\n this.model == MODEL_THINKER ? MAX_STEPS_THINKER : MAX_STEPS_ACTOR;\n if (maxSteps > limit) {\n logger.warn(\n `max_steps (${maxSteps}) exceeds limit for model '${this.model}'. Capping to ${limit}.`,\n );\n maxSteps = limit;\n }\n this.maxSteps = maxSteps;\n this.currentStep = 0;\n logger.info(\n `Task initialized: '${taskDescription}' (max_steps: ${maxSteps})`,\n );\n }\n\n /**\n * Send screenshot to the server and get the next actions.\n *\n * @param screenshot Screenshot as URL string, or raw bytes\n * @param instruction Optional additional instruction for this step (currently unused)\n * @param temperature Sampling temperature for this step (overrides task default if provided)\n */\n async step(\n screenshot: string | ArrayBuffer,\n _instruction?: string,\n temperature?: number,\n ): Promise<Step> {\n this.validateAndIncrementStep();\n logger.debug(`Executing step for task: '${this.taskDescription}'`);\n\n try {\n const screenshotUrl = await this.ensureScreenshotUrl(screenshot);\n this.addUserMessageToHistory(screenshotUrl, this.buildStepPrompt());\n\n const [step, rawOutput] = await this.client.chatCompletions(\n this.model,\n this.messageHistory,\n temperature ?? this.temperature,\n this.taskId,\n );\n if (rawOutput) {\n this.messageHistory.push({\n role: 'assistant',\n content: [\n {\n type: 'text',\n text: rawOutput,\n },\n ],\n });\n }\n if (step.stop) {\n logger.info('Task completed.');\n } else {\n logger.debug(`Step completed with${step.actions.length} actions`);\n }\n\n return step;\n } catch (err) {\n logger.error(`Error during step execution: ${err}`);\n throw err;\n }\n }\n}\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport Actor from '../actor.js';\nimport {\n DEFAULT_MAX_STEPS,\n DEFAULT_STEP_DELAY,\n DEFAULT_TEMPERATURE,\n MODEL_ACTOR,\n} from '../consts.js';\nimport getLogger from '../logger.js';\nimport type {\n ActionEvent,\n ActionHandler,\n ImageProvider,\n StepEvent,\n StepObserver,\n} from '../types/index.js';\nimport type { Agent } from './index.js';\n\nconst logger = getLogger('agent.default');\n\ntype ResettableHandler = ActionHandler & { reset?: () => void };\n\nconst resetHandler = (handler: ResettableHandler) => {\n if (typeof handler.reset === 'function') {\n handler.reset();\n }\n};\n\nconst sleep = (seconds: number) =>\n new Promise<void>(resolve => setTimeout(resolve, seconds * 1000));\n\nexport class DefaultAgent implements Agent {\n /** Default asynchronous agent implementation using OAGI client. */\n\n private api_key?: string;\n private base_url?: string;\n private model: string;\n private max_steps: number;\n private temperature?: number;\n private step_observer?: StepObserver;\n private step_delay: number;\n\n constructor(\n api_key?: string,\n base_url?: string,\n model: string = MODEL_ACTOR,\n max_steps: number = DEFAULT_MAX_STEPS,\n temperature: number | undefined = DEFAULT_TEMPERATURE,\n step_observer?: StepObserver,\n step_delay: number = DEFAULT_STEP_DELAY,\n ) {\n this.api_key = api_key;\n this.base_url = base_url;\n this.model = model;\n this.max_steps = max_steps;\n this.temperature = temperature;\n this.step_observer = step_observer;\n this.step_delay = step_delay;\n }\n\n async execute(\n instruction: string,\n action_handler: ActionHandler,\n image_provider: ImageProvider,\n ): Promise<boolean> {\n const actor = new Actor(this.api_key, this.base_url, this.model);\n\n logger.info(`Starting async task execution: ${instruction}`);\n actor.initTask(instruction, this.max_steps);\n\n // Reset handler state at automation start\n resetHandler(action_handler);\n\n for (let i = 0; i < this.max_steps; i++) {\n const step_num = i + 1;\n logger.debug(`Executing step ${step_num}/${this.max_steps}`);\n\n // Capture current state\n const image = await image_provider.provide();\n\n // Get next step from OAGI\n const step = await actor.step(image, undefined, this.temperature);\n\n // Log reasoning\n if (step.reason) {\n logger.info(`Step ${step_num}: ${step.reason}`);\n }\n\n // Emit step event\n if (this.step_observer) {\n const event: StepEvent = {\n type: 'step',\n timestamp: new Date(),\n step_num,\n image,\n step,\n task_id: (actor as any).taskId,\n };\n await this.step_observer.onEvent(event);\n }\n\n // Execute actions if any\n if (step.actions?.length) {\n logger.info(`Actions (${step.actions.length}):`);\n for (const action of step.actions) {\n const count_suffix =\n action.count && action.count > 1 ? ` x${action.count}` : '';\n logger.info(` [${action.type}] ${action.argument}${count_suffix}`);\n }\n\n let error: string | null = null;\n try {\n await action_handler.handle(step.actions);\n } catch (e) {\n error = String(e);\n throw e;\n } finally {\n // Emit action event\n if (this.step_observer) {\n const event: ActionEvent = {\n type: 'action',\n timestamp: new Date(),\n step_num,\n actions: step.actions,\n error: error ?? undefined,\n };\n await this.step_observer.onEvent(event);\n }\n }\n }\n\n // Wait after actions before next screenshot\n if (this.step_delay > 0) {\n await sleep(this.step_delay);\n }\n\n // Check if task is complete\n if (step.stop) {\n logger.info(`Task completed successfully after ${step_num} steps`);\n return true;\n }\n }\n\n logger.warn(\n `Task reached max steps (${this.max_steps}) without completion`,\n );\n return false;\n }\n}\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport { StepObserver } from '../types/index.js';\nimport { Agent } from './index.js';\n\nexport type AgentCreateOptions = {\n apiKey?: string;\n baseURL?: string;\n model?: string;\n maxSteps?: number;\n temperature?: number;\n stepObserver?: StepObserver | null;\n stepDelay?: number;\n};\n\n// Type alias for agent factory functions\nexport type AgentFactory = (options?: AgentCreateOptions) => Agent;\n\n// Global registry mapping mode names to factory functions\nconst agentRegistry: Record<string, AgentFactory> = {};\n\nexport const asyncAgentRegister = (mode: string) => {\n /**\n * Decorator to register agent factory functions for specific modes.\n *\n * The decorator performs the following:\n * 1. Registers the factory function under the specified mode name\n * 2. Validates that duplicate modes are not registered\n * 3. Enables runtime validation of returned AsyncAgent instances\n *\n * @param mode The agent mode identifier (e.g., \"actor\", \"planner\", \"todo\")\n */\n return (func: AgentFactory): AgentFactory => {\n // Check if mode is already registered\n if (mode in agentRegistry) {\n throw new Error(\n `Agent mode '${mode}' is already registered. Cannot register the same mode twice.`,\n );\n }\n\n // Register the factory\n agentRegistry[mode] = func;\n return func;\n };\n};\n\nexport const getAgentFactory = (mode: string): AgentFactory => {\n /**\n * Get the registered agent factory for a mode.\n */\n if (!(mode in agentRegistry)) {\n const availableModes = Object.keys(agentRegistry);\n throw new Error(\n `Unknown agent mode: '${mode}'. Available modes: ${availableModes}`,\n );\n }\n return agentRegistry[mode]!;\n};\n\nexport const listAgentModes = (): string[] => {\n /**\n * List all registered agent modes.\n */\n return Object.keys(agentRegistry);\n};\n\nexport const createAgent = (\n mode: string,\n options: AgentCreateOptions = {},\n): Agent => {\n /**\n * Create an agent instance using the registered factory for the given mode.\n */\n const factory = getAgentFactory(mode);\n\n const agent = factory(options);\n\n if (!agent || typeof (agent as any).execute !== 'function') {\n throw new TypeError(\n `Factory for mode '${mode}' returned an object that doesn't implement Agent. Expected an object with an 'execute' method.`,\n );\n }\n\n return agent;\n};\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport {\n DEFAULT_MAX_STEPS,\n DEFAULT_MAX_STEPS_TASKER,\n DEFAULT_MAX_STEPS_THINKER,\n DEFAULT_REFLECTION_INTERVAL_TASKER,\n DEFAULT_STEP_DELAY,\n DEFAULT_TEMPERATURE_LOW,\n MODEL_ACTOR,\n MODEL_THINKER,\n} from '../consts.js';\nimport type { StepObserver } from '../types/index.js';\n\nimport { DefaultAgent } from './default.js';\nimport { Agent } from './index.js';\nimport { asyncAgentRegister, type AgentCreateOptions } from './registry.js';\n\nasyncAgentRegister('actor')((options: AgentCreateOptions = {}): Agent => {\n const {\n apiKey,\n baseURL,\n model = MODEL_ACTOR,\n maxSteps = DEFAULT_MAX_STEPS,\n temperature = DEFAULT_TEMPERATURE_LOW,\n stepObserver,\n stepDelay = DEFAULT_STEP_DELAY,\n } = options;\n\n return new DefaultAgent(\n apiKey,\n baseURL,\n model,\n maxSteps,\n temperature,\n stepObserver ?? undefined,\n stepDelay,\n );\n});\n\nasyncAgentRegister('thinker')((options: AgentCreateOptions = {}): Agent => {\n const {\n apiKey,\n baseURL,\n model = MODEL_THINKER,\n maxSteps = DEFAULT_MAX_STEPS_THINKER,\n temperature = DEFAULT_TEMPERATURE_LOW,\n stepObserver,\n stepDelay = DEFAULT_STEP_DELAY,\n } = options;\n\n return new DefaultAgent(\n apiKey,\n baseURL,\n model,\n maxSteps,\n temperature,\n (stepObserver ?? undefined) as StepObserver | undefined,\n stepDelay,\n );\n});\n\n// NOTE: TaskerAgent factories are defined in the python SDK.\n// They will be ported to TypeScript in `src/agent/tasker`.\n// Constants are imported here to keep parity with python.\nexport const _taskerFactoryDefaults = {\n model: MODEL_ACTOR,\n max_steps: DEFAULT_MAX_STEPS_TASKER,\n temperature: DEFAULT_TEMPERATURE_LOW,\n reflection_interval: DEFAULT_REFLECTION_INTERVAL_TASKER,\n step_delay: DEFAULT_STEP_DELAY,\n};\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport type { Action, ActionType, ObserverEvent } from '../../types/index.js';\nimport {\n parseCoords,\n parseDragCoords,\n parseScroll,\n} from '../../types/models/action.js';\n\nconst ensureDir = (dirPath: string) => {\n fs.mkdirSync(dirPath, { recursive: true });\n};\n\ntype ParsedActionCoords =\n | { type: 'click'; x: number; y: number }\n | { type: 'drag'; x1: number; y1: number; x2: number; y2: number }\n | { type: 'scroll'; x: number; y: number; direction: string };\n\nconst parseActionCoords = (action: Action): ParsedActionCoords | null => {\n /**\n * Parse coordinates from action argument for cursor indicators.\n */\n const arg = action.argument.replace(/^\\(|\\)$/g, '');\n\n switch (action.type as ActionType) {\n case 'click':\n case 'left_double':\n case 'left_triple':\n case 'right_single': {\n const coords = parseCoords(arg);\n if (coords) {\n return { type: 'click', x: coords[0], y: coords[1] };\n }\n return null;\n }\n\n case 'drag': {\n const coords = parseDragCoords(arg);\n if (coords) {\n return {\n type: 'drag',\n x1: coords[0],\n y1: coords[1],\n x2: coords[2],\n y2: coords[3],\n };\n }\n return null;\n }\n\n case 'scroll': {\n const result = parseScroll(arg);\n if (result) {\n return {\n type: 'scroll',\n x: result[0],\n y: result[1],\n direction: result[2],\n };\n }\n return null;\n }\n\n default:\n return null;\n }\n};\n\nexport const exportToMarkdown = (\n events: ObserverEvent[],\n filePath: string,\n imagesDir?: string | null,\n) => {\n /**\n * Export events to a Markdown file.\n */\n const outputDir = path.dirname(filePath);\n ensureDir(outputDir);\n\n if (imagesDir) {\n ensureDir(imagesDir);\n }\n\n const lines: string[] = ['# Agent Execution Report\\n'];\n\n for (const event of events) {\n const d =\n event.timestamp instanceof Date\n ? event.timestamp\n : new Date(event.timestamp);\n const timestamp = d.toTimeString().slice(0, 8);\n\n switch (event.type) {\n case 'step':\n lines.push(`\\n## Step ${event.step_num}\\n`);\n lines.push(`**Time:** ${timestamp}\\n`);\n if (event.task_id) {\n lines.push(`**Task ID:** \\`${event.task_id}\\`\\n`);\n }\n\n if (typeof event.image !== 'string') {\n if (imagesDir) {\n const imageFilename = `step_${event.step_num}.png`;\n const imagePath = path.join(imagesDir, imageFilename);\n fs.writeFileSync(imagePath, Buffer.from(event.image));\n const relPath = path.join(path.basename(imagesDir), imageFilename);\n lines.push(`\\n\\n`);\n } else {\n lines.push(\n `\\n*[Screenshot captured - ${event.image.byteLength} bytes]*\\n`,\n );\n }\n } else {\n lines.push(`\\n**Screenshot URL:** ${event.image}\\n`);\n }\n\n if (event.step.reason) {\n lines.push(`\\n**Reasoning:**\\n> ${event.step.reason}\\n`);\n }\n\n if (event.step.actions?.length) {\n lines.push('\\n**Planned Actions:**\\n');\n for (const action of event.step.actions) {\n const countStr =\n action.count && action.count > 1 ? ` (x${action.count})` : '';\n lines.push(`- \\`${action.type}\\`: ${action.argument}${countStr}\\n`);\n }\n }\n\n if (event.step.stop) {\n lines.push('\\n**Status:** Task Complete\\n');\n }\n break;\n\n case 'action':\n lines.push(`\\n### Actions Executed (${timestamp})\\n`);\n if (event.error) {\n lines.push(`\\n**Error:** ${event.error}\\n`);\n } else {\n lines.push('\\n**Result:** Success\\n');\n }\n break;\n\n case 'log':\n lines.push(`\\n> **Log (${timestamp}):** ${event.message}\\n`);\n break;\n\n case 'split':\n if (event.label) {\n lines.push(`\\n---\\n\\n### ${event.label}\\n`);\n } else {\n lines.push('\\n---\\n');\n }\n break;\n\n case 'image':\n break;\n\n case 'plan': {\n const phaseTitles: Record<string, string> = {\n initial: 'Initial Planning',\n reflection: 'Reflection',\n summary: 'Summary',\n };\n const phaseTitle = phaseTitles[event.phase] ?? event.phase;\n\n lines.push(`\\n### ${phaseTitle} (${timestamp})\\n`);\n if (event.request_id) {\n lines.push(`**Request ID:** \\`${event.request_id}\\`\\n`);\n }\n\n if (event.image) {\n if (typeof event.image !== 'string') {\n if (imagesDir) {\n const imageFilename = `plan_${event.phase}_${Date.now()}.png`;\n const imagePath = path.join(imagesDir, imageFilename);\n fs.writeFileSync(imagePath, Buffer.from(event.image));\n const relPath = path.join(\n path.basename(imagesDir),\n imageFilename,\n );\n lines.push(`\\n\\n`);\n } else {\n lines.push(\n `\\n*[Screenshot captured - ${event.image.byteLength} bytes]*\\n`,\n );\n }\n } else {\n lines.push(`\\n**Screenshot URL:** ${event.image}\\n`);\n }\n }\n\n if (event.reasoning) {\n lines.push(`\\n**Reasoning:**\\n> ${event.reasoning}\\n`);\n }\n\n if (event.result) {\n lines.push(`\\n**Result:** ${event.result}\\n`);\n }\n break;\n }\n }\n }\n\n fs.writeFileSync(filePath, lines.join(''), 'utf-8');\n};\n\ntype HtmlStepEvent = {\n event_type: 'step';\n timestamp: string;\n step_num: number;\n image: string | null;\n action_coords: ParsedActionCoords[];\n reason?: string;\n actions: { type: string; argument: string; count: number }[];\n stop: boolean;\n task_id?: string | null;\n};\n\ntype HtmlActionEvent = {\n event_type: 'action';\n timestamp: string;\n error?: string | null;\n};\n\ntype HtmlLogEvent = {\n event_type: 'log';\n timestamp: string;\n message: string;\n};\n\ntype HtmlSplitEvent = {\n event_type: 'split';\n timestamp: string;\n label: string;\n};\n\ntype HtmlPlanEvent = {\n event_type: 'plan';\n timestamp: string;\n phase: string;\n image: string | null;\n reasoning: string;\n result?: string | null;\n request_id?: string | null;\n};\n\ntype HtmlEvent =\n | HtmlStepEvent\n | HtmlActionEvent\n | HtmlLogEvent\n | HtmlSplitEvent\n | HtmlPlanEvent;\n\nconst convertEventsForHtml = (events: ObserverEvent[]): HtmlEvent[] => {\n /** Convert events to JSON-serializable format for HTML template. */\n const result: HtmlEvent[] = [];\n\n for (const event of events) {\n const d =\n event.timestamp instanceof Date\n ? event.timestamp\n : new Date(event.timestamp);\n const timestamp = d.toTimeString().slice(0, 8);\n\n switch (event.type) {\n case 'step': {\n const action_coords: ParsedActionCoords[] = [];\n const actions: { type: string; argument: string; count: number }[] = [];\n\n if (event.step.actions?.length) {\n for (const action of event.step.actions) {\n const coords = parseActionCoords(action);\n if (coords) {\n action_coords.push(coords);\n }\n actions.push({\n type: action.type,\n argument: action.argument,\n count: action.count ?? 1,\n });\n }\n }\n\n let image: string | null = null;\n if (typeof event.image !== 'string') {\n image = Buffer.from(event.image).toString('base64');\n } else {\n image = event.image;\n }\n\n result.push({\n event_type: 'step',\n timestamp,\n step_num: event.step_num,\n image,\n action_coords,\n reason: event.step.reason,\n actions,\n stop: event.step.stop,\n task_id: event.task_id,\n });\n break;\n }\n\n case 'action':\n result.push({\n event_type: 'action',\n timestamp,\n error: event.error ?? null,\n });\n break;\n\n case 'log':\n result.push({ event_type: 'log', timestamp, message: event.message });\n break;\n\n case 'split':\n result.push({ event_type: 'split', timestamp, label: event.label! });\n break;\n\n case 'image':\n break;\n\n case 'plan': {\n let image: string | null = null;\n if (event.image) {\n if (typeof event.image !== 'string') {\n image = Buffer.from(event.image).toString('base64');\n } else {\n image = event.image;\n }\n }\n\n result.push({\n event_type: 'plan',\n timestamp,\n phase: event.phase,\n image,\n reasoning: event.reasoning,\n result: event.result ?? null,\n request_id: event.request_id ?? null,\n });\n break;\n }\n }\n }\n\n return result;\n};\n\nexport const exportToHtml = (events: ObserverEvent[], filePath: string) => {\n /**\n * Export events to a self-contained HTML file.\n */\n const outputDir = path.dirname(filePath);\n ensureDir(outputDir);\n\n const moduleUrl = (import.meta as any)?.url\n ? (import.meta as any).url\n : pathToFileURL(__filename).href;\n const moduleDir = path.dirname(fileURLToPath(moduleUrl));\n const templatePath = path.join(moduleDir, 'report_template.html');\n const template = fs.readFileSync(templatePath, 'utf-8');\n\n const eventsData = convertEventsForHtml(events);\n const eventsJson = JSON.stringify(eventsData);\n\n const htmlContent = template.replace('{EVENTS_DATA}', eventsJson);\n fs.writeFileSync(filePath, htmlContent, 'utf-8');\n};\n\nexport const exportToJson = (events: ObserverEvent[], filePath: string) => {\n /**\n * Export events to a JSON file.\n */\n const outputDir = path.dirname(filePath);\n ensureDir(outputDir);\n\n const jsonEvents = events.map(event => {\n const timestamp =\n event.timestamp instanceof Date\n ? event.timestamp.toISOString()\n : new Date(event.timestamp).toISOString();\n // Handle ArrayBuffer images before JSON to avoid binary output\n if ('image' in event && event.image instanceof ArrayBuffer) {\n return {\n ...event,\n timestamp,\n image: Buffer.from(event.image).toString('base64'),\n image_encoding: 'base64',\n };\n }\n\n return {\n ...event,\n timestamp,\n };\n });\n\n fs.writeFileSync(filePath, JSON.stringify(jsonEvents, null, 2), 'utf-8');\n};\n","/**\n * -----------------------------------------------------------------------------\n * Copyright (c) OpenAGI Foundation\n * All rights reserved.\n *\n * This file is part of the official API project.\n * Licensed under the MIT License.\n * -----------------------------------------------------------------------------\n */\n\nimport {\n StepObserver,\n type LogEvent,\n type ObserverEvent,\n type SplitEvent,\n} from '../../types/index.js';\nimport { exportToHtml, exportToJson, exportToMarkdown } from './exporters';\n\nexport enum ExportFormat {\n /** Supported export formats. */\n MARKDOWN = 'markdown',\n HTML = 'html',\n JSON = 'json',\n}\n\nexport class AsyncAgentObserver extends StepObserver {\n /**\n * Records agent execution events and exports to various formats.\n *\n * This class implements the AsyncObserver protocol and provides\n * functionality for recording events during agent execution and\n * exporting them to Markdown or HTML formats.\n */\n\n events: ObserverEvent[] = [];\n\n async onEvent(event: ObserverEvent): Promise<void> {\n /**\n * Record an event.\n *\n * @param event The event to record.\n */\n this.events.push(event);\n }\n\n addLog(message: string): void {\n /**\n * Add a custom log message.\n *\n * @param message The log message to add.\n */\n const event: LogEvent = {\n type: 'log',\n timestamp: new Date(),\n message,\n };\n this.events.push(event);\n }\n\n addSplit(label: string = ''): void {\n /**\n * Add a visual separator.\n *\n * @param label Optional label for the separator.\n */\n const event: SplitEvent = {\n type: 'split',\n timestamp: new Date(),\n label,\n };\n this.events.push(event);\n }\n\n clear(): void {\n /** Clear all recorded events. */\n this.events = [];\n }\n\n getEventsByStep(step_num: number): ObserverEvent[] {\n /**\n * Get all events for a specific step.\n *\n * @param step_num The step number to filter by.\n */\n return this.events.filter(\n event =>\n (event as any).step_num !== undefined &&\n (event as any).step_num === step_num,\n );\n }\n\n export(\n format: ExportFormat | string,\n path: string,\n images_dir?: string | null,\n ): void {\n /**\n * Export recorded events to a file.\n *\n * @param format Export format (markdown, html, json)\n * @param path Path to the output file.\n * @param images_dir Directory to save images (markdown only).\n */\n const normalized =\n typeof format === 'string'\n ? (format.toLowerCase() as ExportFormat)\n : format;\n\n switch (normalized) {\n case ExportFormat.MARKDOWN:\n exportToMarkdown(this.events, path, images_dir ?? undefined);\n return;\n case ExportFormat.HTML:\n exportToHtml(this.events, path);\n return;\n case ExportFormat.JSON:\n exportToJson(this.events, path);\n return;\n default:\n throw new Error(`Unknown export format: ${String(format)}`);\n }\n }\n}\n","import { ActionHandler, ImageProvider } from './types/index.js';\nimport type { Action } from './types/models/action.js';\nimport {\n parseCoords,\n parseDragCoords,\n parseScroll,\n} from './types/models/action.js';\nimport {\n type ImageConfig,\n ImageConfigSchema,\n} from './types/models/image-config.js';\nimport robot from 'robotjs';\nimport sharp from 'sharp';\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise(r => setTimeout(r, ms));\n\ntype SharpResizeKernel =\n | 'nearest'\n | 'cubic'\n | 'mitchell'\n | 'lanczos2'\n | 'lanczos3';\n\nconst toSharpKernel = (\n resample: ImageConfig['resample'],\n): SharpResizeKernel => {\n switch (resample) {\n case 'NEAREST':\n return 'nearest';\n case 'BICUBIC':\n return 'cubic';\n case 'BILINEAR':\n return 'mitchell';\n case 'LANCZOS':\n default:\n return 'lanczos3';\n }\n};\n\nconst normalizeKey = (\n raw: string,\n opts: { macosCtrlToCmd: boolean },\n): string => {\n const key = raw.trim().toLowerCase();\n if (key === 'caps_lock' || key === 'caps') return 'capslock';\n if (key === 'page_up' || key === 'pageup') return 'pageup';\n if (key === 'page_down' || key === 'pagedown') return 'pagedown';\n if (key === 'cmd') return 'command';\n if (opts.macosCtrlToCmd && process.platform === 'darwin' && key === 'ctrl') {\n return 'command';\n }\n if (key === 'ctrl') return 'control';\n return key;\n};\n\nconst parseHotkey = (\n arg: string,\n opts: { macosCtrlToCmd: boolean },\n): string[] => {\n const s = arg.trim().replace(/^\\(/, '').replace(/\\)$/, '');\n return s\n .split('+')\n .map(k => normalizeKey(k, opts))\n .filter(Boolean);\n};\n\nconst stripOuterParens = (s: string): string =>\n s.trim().replace(/^\\(/, '').replace(/\\)$/, '');\n\nconst applySessionCaps = (text: string, enabled: boolean): string => {\n if (!enabled) return text;\n return text\n .split('')\n .map(c => (/[a-z]/i.test(c) ? c.toUpperCase() : c))\n .join('');\n};\n\nexport type DesktopAutomationConfig = {\n dragDurationMs?: number;\n scrollAmount?: number;\n waitDurationMs?: number;\n hotkeyDelayMs?: number;\n macosCtrlToCmd?: boolean;\n capslockMode?: 'session' | 'system';\n};\n\nconst defaultDesktopAutomationConfig =\n (): Required<DesktopAutomationConfig> => ({\n dragDurationMs: 500,\n scrollAmount: process.platform === 'darwin' ? 2 : 100,\n waitDurationMs: 1000,\n hotkeyDelayMs: 100,\n macosCtrlToCmd: true,\n capslockMode: 'session',\n });\n\nexport class ScreenshotMaker implements ImageProvider {\n #cfg: ImageConfig;\n\n constructor(cfg?: Partial<ImageConfig>) {\n const defaultConfig = ImageConfigSchema.parse({});\n this.#cfg = { ...defaultConfig, ...cfg };\n }\n\n static toArrayBuffer(buffer: Buffer) {\n const arraybuffer = new ArrayBuffer(buffer.length);\n const view = new Uint8Array(arraybuffer);\n for (let i = 0; i < buffer.length; ++i) {\n view[i] = buffer[i];\n }\n return arraybuffer;\n }\n\n async provide() {\n const { width, height } = robot.getScreenSize();\n const screenshot = robot.screen.capture(0, 0, width, height);\n\n const channels = 3;\n const data = new Uint8Array(\n screenshot.width * screenshot.height * channels,\n );\n for (let w = 0; w < screenshot.width; ++w) {\n for (let h = 0; h < screenshot.height; ++h) {\n let offset = (h * screenshot.width + w) * channels;\n let offset2 = screenshot.byteWidth * h + w * screenshot.bytesPerPixel;\n data[offset] = screenshot.image.readUInt8(offset2 + 2);\n data[offset + 1] = screenshot.image.readUInt8(offset2 + 1);\n data[offset + 2] = screenshot.image.readUInt8(offset2 + 0);\n }\n }\n let p = sharp(Buffer.from(data), {\n raw: {\n width: screenshot.width,\n height: screenshot.height,\n channels,\n },\n });\n\n if (this.#cfg.width || this.#cfg.height) {\n p = p.resize(this.#cfg.width ?? width, this.#cfg.height ?? height, {\n fit: 'fill',\n kernel: toSharpKernel(this.#cfg.resample),\n });\n }\n\n const encoded =\n this.#cfg.format === 'PNG'\n ? await p\n .png({ compressionLevel: this.#cfg.optimize ? 9 : 6 })\n .toBuffer()\n : await p.jpeg({ quality: this.#cfg.quality }).toBuffer();\n return ScreenshotMaker.toArrayBuffer(encoded);\n }\n}\n\nexport class DefaultActionHandler implements ActionHandler {\n readonly #cfg: Required<DesktopAutomationConfig>;\n #sessionCapsEnabled = false;\n\n constructor(cfg?: DesktopAutomationConfig) {\n this.#cfg = { ...defaultDesktopAutomationConfig(), ...cfg };\n }\n\n reset(): void {\n this.#sessionCapsEnabled = false;\n }\n\n async handle(actions: Action[]): Promise<void> {\n for (const action of actions) {\n const count = action.count ?? 1;\n for (let i = 0; i < count; i++) {\n await this.#handleOne(action);\n }\n }\n }\n\n #denormalize(x: number, y: number): { x: number; y: number } {\n const { width, height } = robot.getScreenSize();\n\n let px = Math.floor((x * width) / 1000);\n let py = Math.floor((y * height) / 1000);\n\n if (px < 1) px = 1;\n if (px > width - 1) px = width - 1;\n if (py < 1) py = 1;\n if (py > height - 1) py = height - 1;\n\n return { x: px, y: py };\n }\n\n async #handleOne(action: Action): Promise<void> {\n const arg = stripOuterParens(action.argument);\n\n switch (action.type) {\n case 'click': {\n const coords = parseCoords(arg);\n if (!coords) throw new Error(`Invalid coords: ${arg}`);\n const p = this.#denormalize(coords[0], coords[1]);\n robot.moveMouse(p.x, p.y);\n robot.mouseClick('left', false);\n return;\n }\n\n case 'left_double': {\n const coords = parseCoords(arg);\n if (!coords) throw new Error(`Invalid coords: ${arg}`);\n const p = this.#denormalize(coords[0], coords[1]);\n robot.moveMouse(p.x, p.y);\n robot.mouseClick('left', true);\n return;\n }\n\n case 'left_triple': {\n const coords = parseCoords(arg);\n if (!coords) throw new Error(`Invalid coords: ${arg}`);\n const p = this.#denormalize(coords[0], coords[1]);\n robot.moveMouse(p.x, p.y);\n robot.mouseClick('left', true);\n robot.mouseClick('left', false);\n return;\n }\n\n case 'right_single': {\n const coords = parseCoords(arg);\n if (!coords) throw new Error(`Invalid coords: ${arg}`);\n const p = this.#denormalize(coords[0], coords[1]);\n robot.moveMouse(p.x, p.y);\n robot.mouseClick('right', false);\n return;\n }\n\n case 'drag': {\n const coords = parseDragCoords(arg);\n if (!coords) throw new Error(`Invalid drag coords: ${arg}`);\n const p1 = this.#denormalize(coords[0], coords[1]);\n const p2 = this.#denormalize(coords[2], coords[3]);\n robot.moveMouse(p1.x, p1.y);\n robot.mouseToggle('down', 'left');\n robot.dragMouse(p2.x, p2.y);\n await sleep(this.#cfg.dragDurationMs);\n robot.mouseToggle('up', 'left');\n return;\n }\n\n case 'hotkey': {\n const keys = parseHotkey(arg, {\n macosCtrlToCmd: this.#cfg.macosCtrlToCmd,\n });\n\n if (keys.length === 1 && keys[0] === 'capslock') {\n if (this.#cfg.capslockMode === 'system') {\n robot.keyTap('capslock');\n } else {\n this.#sessionCapsEnabled = !this.#sessionCapsEnabled;\n }\n return;\n }\n\n const last = keys.at(-1);\n if (!last) return;\n const modifiers = keys.slice(0, -1) as Array<\n 'alt' | 'command' | 'control' | 'shift'\n >;\n\n robot.keyTap(last, modifiers.length ? modifiers : []);\n await sleep(this.#cfg.hotkeyDelayMs);\n return;\n }\n\n case 'type': {\n const raw = arg.replace(/^['\"]/, '').replace(/['\"]$/, '');\n const text = applySessionCaps(raw, this.#sessionCapsEnabled);\n robot.typeString(text);\n return;\n }\n\n case 'scroll': {\n const parsed = parseScroll(arg);\n if (!parsed) throw new Error(`Invalid scroll: ${arg}`);\n const p = this.#denormalize(parsed[0], parsed[1]);\n const direction = parsed[2];\n robot.moveMouse(p.x, p.y);\n const amount =\n direction === 'up' ? this.#cfg.scrollAmount : -this.#cfg.scrollAmount;\n robot.scrollMouse(0, amount);\n return;\n }\n\n case 'wait': {\n await sleep(this.#cfg.waitDurationMs);\n return;\n }\n\n case 'finish': {\n this.reset();\n return;\n }\n\n case 'call_user': {\n return;\n }\n\n default: {\n const exhaustive: never = action.type;\n throw new Error(`Unknown action type: ${String(exhaustive)}`);\n }\n }\n }\n}\n"],"mappings":"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","names":["z","z","z","action","logger","logger","logger","path","sleep"]}
|
package/dist/cli.cjs
CHANGED
|
@@ -758,8 +758,18 @@ ${taskDescription}
|
|
|
758
758
|
// src/client.ts
|
|
759
759
|
var logger2 = logger_default("client");
|
|
760
760
|
var _Client = class _Client {
|
|
761
|
-
|
|
762
|
-
|
|
761
|
+
baseURL;
|
|
762
|
+
apiKey;
|
|
763
|
+
timeout = HTTP_CLIENT_TIMEOUT;
|
|
764
|
+
client;
|
|
765
|
+
constructor(baseURL, apiKey, maxRetries) {
|
|
766
|
+
if (typeof baseURL === "object") {
|
|
767
|
+
({ baseURL, apiKey, maxRetries } = baseURL);
|
|
768
|
+
}
|
|
769
|
+
baseURL ??= process.env.OAGI_BASE_URL ?? DEFAULT_BASE_URL;
|
|
770
|
+
apiKey ??= process.env.OAGI_API_KEY;
|
|
771
|
+
maxRetries ??= DEFAULT_MAX_RETRIES;
|
|
772
|
+
this.baseURL = baseURL;
|
|
763
773
|
this.apiKey = apiKey;
|
|
764
774
|
if (!apiKey) {
|
|
765
775
|
throw new ConfigurationError(
|
|
@@ -767,19 +777,17 @@ var _Client = class _Client {
|
|
|
767
777
|
);
|
|
768
778
|
}
|
|
769
779
|
this.client = new import_openai.default({
|
|
770
|
-
baseURL: new URL("./v1",
|
|
780
|
+
baseURL: new URL("./v1", baseURL).href,
|
|
771
781
|
apiKey,
|
|
772
782
|
maxRetries
|
|
773
783
|
});
|
|
774
|
-
logger2.info(`Client initialized with base_url: ${
|
|
784
|
+
logger2.info(`Client initialized with base_url: ${baseURL}`);
|
|
775
785
|
}
|
|
776
|
-
timeout = HTTP_CLIENT_TIMEOUT;
|
|
777
|
-
client;
|
|
778
786
|
fetch(input, init) {
|
|
779
787
|
if (typeof input === "string" || input instanceof URL) {
|
|
780
|
-
input = new URL(input, this.
|
|
788
|
+
input = new URL(input, this.baseURL);
|
|
781
789
|
} else {
|
|
782
|
-
input = new URL(input.url, this.
|
|
790
|
+
input = new URL(input.url, this.baseURL);
|
|
783
791
|
}
|
|
784
792
|
init ??= {};
|
|
785
793
|
const signal = AbortSignal.timeout(this.timeout * 1e3);
|
|
@@ -848,7 +856,10 @@ var _Client = class _Client {
|
|
|
848
856
|
task_id: taskId
|
|
849
857
|
});
|
|
850
858
|
const rawOutput = response.choices[0].message.content ?? "";
|
|
851
|
-
const step =
|
|
859
|
+
const step = {
|
|
860
|
+
...parseRawOutput(rawOutput),
|
|
861
|
+
usage: response.usage
|
|
862
|
+
};
|
|
852
863
|
taskId = response.task_id;
|
|
853
864
|
const task = taskId ? `task_id: ${taskId}, ` : "";
|
|
854
865
|
const usage = response.usage ? `, tokens: ${response.usage.prompt_tokens}+${response.usage.completion_tokens}` : "";
|
|
@@ -1002,10 +1013,10 @@ var Client = _Client;
|
|
|
1002
1013
|
// src/actor.ts
|
|
1003
1014
|
var logger3 = logger_default("task");
|
|
1004
1015
|
var Actor = class {
|
|
1005
|
-
constructor(apiKey,
|
|
1016
|
+
constructor(apiKey, baseURL, model = MODEL_ACTOR, temperature) {
|
|
1006
1017
|
this.model = model;
|
|
1007
1018
|
this.temperature = temperature;
|
|
1008
|
-
this.client = new Client(
|
|
1019
|
+
this.client = new Client(baseURL, apiKey);
|
|
1009
1020
|
}
|
|
1010
1021
|
/**
|
|
1011
1022
|
* Client-side generated UUID
|
|
@@ -1170,7 +1181,7 @@ var DefaultAgent = class {
|
|
|
1170
1181
|
async execute(instruction, action_handler, image_provider) {
|
|
1171
1182
|
const actor = new Actor(this.api_key, this.base_url, this.model);
|
|
1172
1183
|
logger4.info(`Starting async task execution: ${instruction}`);
|
|
1173
|
-
|
|
1184
|
+
actor.initTask(instruction, this.max_steps);
|
|
1174
1185
|
resetHandler(action_handler);
|
|
1175
1186
|
for (let i = 0; i < this.max_steps; i++) {
|
|
1176
1187
|
const step_num = i + 1;
|
|
@@ -1271,7 +1282,7 @@ var createAgent = (mode, options = {}) => {
|
|
|
1271
1282
|
asyncAgentRegister("actor")((options = {}) => {
|
|
1272
1283
|
const {
|
|
1273
1284
|
apiKey,
|
|
1274
|
-
|
|
1285
|
+
baseURL,
|
|
1275
1286
|
model = MODEL_ACTOR,
|
|
1276
1287
|
maxSteps = DEFAULT_MAX_STEPS,
|
|
1277
1288
|
temperature = DEFAULT_TEMPERATURE_LOW,
|
|
@@ -1280,7 +1291,7 @@ asyncAgentRegister("actor")((options = {}) => {
|
|
|
1280
1291
|
} = options;
|
|
1281
1292
|
return new DefaultAgent(
|
|
1282
1293
|
apiKey,
|
|
1283
|
-
|
|
1294
|
+
baseURL,
|
|
1284
1295
|
model,
|
|
1285
1296
|
maxSteps,
|
|
1286
1297
|
temperature,
|
|
@@ -1291,7 +1302,7 @@ asyncAgentRegister("actor")((options = {}) => {
|
|
|
1291
1302
|
asyncAgentRegister("thinker")((options = {}) => {
|
|
1292
1303
|
const {
|
|
1293
1304
|
apiKey,
|
|
1294
|
-
|
|
1305
|
+
baseURL,
|
|
1295
1306
|
model = MODEL_THINKER,
|
|
1296
1307
|
maxSteps = DEFAULT_MAX_STEPS_THINKER,
|
|
1297
1308
|
temperature = DEFAULT_TEMPERATURE_LOW,
|
|
@@ -1300,7 +1311,7 @@ asyncAgentRegister("thinker")((options = {}) => {
|
|
|
1300
1311
|
} = options;
|
|
1301
1312
|
return new DefaultAgent(
|
|
1302
1313
|
apiKey,
|
|
1303
|
-
|
|
1314
|
+
baseURL,
|
|
1304
1315
|
model,
|
|
1305
1316
|
maxSteps,
|
|
1306
1317
|
temperature,
|
|
@@ -1650,7 +1661,7 @@ Get your API key at ${API_KEY_HELP_URL}
|
|
|
1650
1661
|
process.exitCode = 1;
|
|
1651
1662
|
return;
|
|
1652
1663
|
}
|
|
1653
|
-
const
|
|
1664
|
+
const baseURL = opts.oagiBaseUrl ?? process.env.OAGI_BASE_URL ?? DEFAULT_BASE_URL;
|
|
1654
1665
|
const mode = opts.mode ?? MODE_ACTOR;
|
|
1655
1666
|
const stepDelay = opts.stepDelay ?? DEFAULT_STEP_DELAY;
|
|
1656
1667
|
const exportFormat = opts.export;
|
|
@@ -1659,7 +1670,7 @@ Get your API key at ${API_KEY_HELP_URL}
|
|
|
1659
1670
|
const agentObserver = exportFormat ? new AsyncAgentObserver() : null;
|
|
1660
1671
|
const createOpts = {
|
|
1661
1672
|
apiKey,
|
|
1662
|
-
|
|
1673
|
+
baseURL,
|
|
1663
1674
|
stepObserver: stepTracker.chain(agentObserver),
|
|
1664
1675
|
stepDelay
|
|
1665
1676
|
};
|