@oagi/oagi 0.1.3 → 0.1.5
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/dist/agent_observer.ts +123 -0
- package/dist/{chunk-SDBYP57G.js → chunk-SRTB44IH.js} +1044 -88
- package/dist/chunk-SRTB44IH.js.map +1 -0
- package/dist/cli.cjs +981 -32
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/events.ts +21 -0
- package/dist/exporters.ts +432 -0
- package/dist/index.cjs +1361 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +176 -22
- package/dist/index.d.ts +176 -22
- package/dist/index.js +7 -1
- package/dist/index.ts +23 -0
- package/dist/protocol.ts +14 -0
- package/dist/report_template.html +474 -0
- package/package.json +7 -6
- package/README.md +0 -154
- package/dist/chunk-SDBYP57G.js.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -478,7 +478,21 @@ var exportToHtml = (events, filePath) => {
|
|
|
478
478
|
ensureDir(outputDir);
|
|
479
479
|
const moduleUrl = import_meta?.url ? import_meta.url : (0, import_node_url.pathToFileURL)(__filename).href;
|
|
480
480
|
const moduleDir = import_node_path.default.dirname((0, import_node_url.fileURLToPath)(moduleUrl));
|
|
481
|
-
const
|
|
481
|
+
const primaryTemplate = import_node_path.default.join(moduleDir, "report_template.html");
|
|
482
|
+
const fallbackTemplate = import_node_path.default.resolve(
|
|
483
|
+
moduleDir,
|
|
484
|
+
"..",
|
|
485
|
+
"src",
|
|
486
|
+
"agent",
|
|
487
|
+
"observer",
|
|
488
|
+
"report_template.html"
|
|
489
|
+
);
|
|
490
|
+
const templatePath = import_node_fs.default.existsSync(primaryTemplate) ? primaryTemplate : fallbackTemplate;
|
|
491
|
+
if (!import_node_fs.default.existsSync(templatePath)) {
|
|
492
|
+
throw new Error(
|
|
493
|
+
`Report template not found at ${primaryTemplate} or ${fallbackTemplate}`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
482
496
|
const template = import_node_fs.default.readFileSync(templatePath, "utf-8");
|
|
483
497
|
const eventsData = convertEventsForHtml(events);
|
|
484
498
|
const eventsJson = JSON.stringify(eventsData);
|
|
@@ -571,8 +585,11 @@ var MODEL_THINKER = "lux-thinker-1";
|
|
|
571
585
|
var MODE_ACTOR = "actor";
|
|
572
586
|
var DEFAULT_MAX_STEPS = 20;
|
|
573
587
|
var DEFAULT_MAX_STEPS_THINKER = 100;
|
|
588
|
+
var DEFAULT_MAX_STEPS_TASKER = 60;
|
|
574
589
|
var MAX_STEPS_ACTOR = 30;
|
|
575
590
|
var MAX_STEPS_THINKER = 120;
|
|
591
|
+
var DEFAULT_REFLECTION_INTERVAL = 4;
|
|
592
|
+
var DEFAULT_REFLECTION_INTERVAL_TASKER = 20;
|
|
576
593
|
var DEFAULT_STEP_DELAY = 0.3;
|
|
577
594
|
var DEFAULT_TEMPERATURE = 0.5;
|
|
578
595
|
var DEFAULT_TEMPERATURE_LOW = 0.1;
|
|
@@ -659,6 +676,39 @@ var logTraceOnFailure = (_, __, descriptor) => {
|
|
|
659
676
|
return descriptor;
|
|
660
677
|
};
|
|
661
678
|
|
|
679
|
+
// src/platform-info.ts
|
|
680
|
+
var import_module = require("module");
|
|
681
|
+
var import_meta2 = {};
|
|
682
|
+
var SDK_NAME = "oagi-typescript";
|
|
683
|
+
function getSdkVersion() {
|
|
684
|
+
try {
|
|
685
|
+
const require2 = (0, import_module.createRequire)(import_meta2.url);
|
|
686
|
+
for (const p of ["../package.json", "../../package.json"]) {
|
|
687
|
+
try {
|
|
688
|
+
const pkg = require2(p);
|
|
689
|
+
if (pkg.version && pkg.version !== "0.0.0") return pkg.version;
|
|
690
|
+
} catch {
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
} catch {
|
|
694
|
+
}
|
|
695
|
+
return "unknown";
|
|
696
|
+
}
|
|
697
|
+
function getUserAgent() {
|
|
698
|
+
return `${SDK_NAME}/${getSdkVersion()} (node ${process.version}; ${process.platform}; ${process.arch})`;
|
|
699
|
+
}
|
|
700
|
+
function getSdkHeaders() {
|
|
701
|
+
return {
|
|
702
|
+
"User-Agent": getUserAgent(),
|
|
703
|
+
"x-sdk-name": SDK_NAME,
|
|
704
|
+
"x-sdk-version": getSdkVersion(),
|
|
705
|
+
"x-sdk-language": "typescript",
|
|
706
|
+
"x-sdk-language-version": process.version,
|
|
707
|
+
"x-sdk-os": process.platform,
|
|
708
|
+
"x-sdk-platform": process.arch
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
|
|
662
712
|
// src/utils/output-parser.ts
|
|
663
713
|
var splitActions = (actionBlock) => {
|
|
664
714
|
const actions = [];
|
|
@@ -758,28 +808,38 @@ ${taskDescription}
|
|
|
758
808
|
// src/client.ts
|
|
759
809
|
var logger2 = logger_default("client");
|
|
760
810
|
var _Client = class _Client {
|
|
761
|
-
|
|
762
|
-
|
|
811
|
+
baseURL;
|
|
812
|
+
apiKey;
|
|
813
|
+
timeout = HTTP_CLIENT_TIMEOUT;
|
|
814
|
+
client;
|
|
815
|
+
constructor(baseURL, apiKey, maxRetries) {
|
|
816
|
+
if (typeof baseURL === "object") {
|
|
817
|
+
({ baseURL, apiKey, maxRetries } = baseURL);
|
|
818
|
+
}
|
|
819
|
+
baseURL ??= process.env.OAGI_BASE_URL ?? DEFAULT_BASE_URL;
|
|
820
|
+
apiKey ??= process.env.OAGI_API_KEY;
|
|
821
|
+
maxRetries ??= DEFAULT_MAX_RETRIES;
|
|
822
|
+
this.baseURL = baseURL;
|
|
763
823
|
this.apiKey = apiKey;
|
|
764
824
|
if (!apiKey) {
|
|
765
825
|
throw new ConfigurationError(
|
|
766
826
|
`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}`
|
|
767
827
|
);
|
|
768
828
|
}
|
|
829
|
+
const sdkHeaders = getSdkHeaders();
|
|
769
830
|
this.client = new import_openai.default({
|
|
770
|
-
baseURL: new URL("./v1",
|
|
831
|
+
baseURL: new URL("./v1", baseURL).href,
|
|
771
832
|
apiKey,
|
|
772
|
-
maxRetries
|
|
833
|
+
maxRetries,
|
|
834
|
+
defaultHeaders: sdkHeaders
|
|
773
835
|
});
|
|
774
|
-
logger2.info(`Client initialized with base_url: ${
|
|
836
|
+
logger2.info(`Client initialized with base_url: ${baseURL}`);
|
|
775
837
|
}
|
|
776
|
-
timeout = HTTP_CLIENT_TIMEOUT;
|
|
777
|
-
client;
|
|
778
838
|
fetch(input, init) {
|
|
779
839
|
if (typeof input === "string" || input instanceof URL) {
|
|
780
|
-
input = new URL(input, this.
|
|
840
|
+
input = new URL(input, this.baseURL);
|
|
781
841
|
} else {
|
|
782
|
-
input = new URL(input.url, this.
|
|
842
|
+
input = new URL(input.url, this.baseURL);
|
|
783
843
|
}
|
|
784
844
|
init ??= {};
|
|
785
845
|
const signal = AbortSignal.timeout(this.timeout * 1e3);
|
|
@@ -787,7 +847,7 @@ var _Client = class _Client {
|
|
|
787
847
|
return fetch(input, init);
|
|
788
848
|
}
|
|
789
849
|
buildHeaders(apiVersion) {
|
|
790
|
-
const headers =
|
|
850
|
+
const headers = getSdkHeaders();
|
|
791
851
|
if (apiVersion) {
|
|
792
852
|
headers["x-api-version"] = apiVersion;
|
|
793
853
|
}
|
|
@@ -848,7 +908,10 @@ var _Client = class _Client {
|
|
|
848
908
|
task_id: taskId
|
|
849
909
|
});
|
|
850
910
|
const rawOutput = response.choices[0].message.content ?? "";
|
|
851
|
-
const step =
|
|
911
|
+
const step = {
|
|
912
|
+
...parseRawOutput(rawOutput),
|
|
913
|
+
usage: response.usage
|
|
914
|
+
};
|
|
852
915
|
taskId = response.task_id;
|
|
853
916
|
const task = taskId ? `task_id: ${taskId}, ` : "";
|
|
854
917
|
const usage = response.usage ? `, tokens: ${response.usage.prompt_tokens}+${response.usage.completion_tokens}` : "";
|
|
@@ -1002,10 +1065,10 @@ var Client = _Client;
|
|
|
1002
1065
|
// src/actor.ts
|
|
1003
1066
|
var logger3 = logger_default("task");
|
|
1004
1067
|
var Actor = class {
|
|
1005
|
-
constructor(apiKey,
|
|
1068
|
+
constructor(apiKey, baseURL, model = MODEL_ACTOR, temperature) {
|
|
1006
1069
|
this.model = model;
|
|
1007
1070
|
this.temperature = temperature;
|
|
1008
|
-
this.client = new Client(
|
|
1071
|
+
this.client = new Client(baseURL, apiKey);
|
|
1009
1072
|
}
|
|
1010
1073
|
/**
|
|
1011
1074
|
* Client-side generated UUID
|
|
@@ -1170,7 +1233,7 @@ var DefaultAgent = class {
|
|
|
1170
1233
|
async execute(instruction, action_handler, image_provider) {
|
|
1171
1234
|
const actor = new Actor(this.api_key, this.base_url, this.model);
|
|
1172
1235
|
logger4.info(`Starting async task execution: ${instruction}`);
|
|
1173
|
-
|
|
1236
|
+
actor.initTask(instruction, this.max_steps);
|
|
1174
1237
|
resetHandler(action_handler);
|
|
1175
1238
|
for (let i = 0; i < this.max_steps; i++) {
|
|
1176
1239
|
const step_num = i + 1;
|
|
@@ -1231,6 +1294,784 @@ var DefaultAgent = class {
|
|
|
1231
1294
|
}
|
|
1232
1295
|
};
|
|
1233
1296
|
|
|
1297
|
+
// src/agent/tasker.ts
|
|
1298
|
+
var logger5 = logger_default("agent.tasker");
|
|
1299
|
+
var resetHandler2 = (handler) => {
|
|
1300
|
+
if (typeof handler.reset === "function") {
|
|
1301
|
+
handler.reset();
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
var sleep2 = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
|
|
1305
|
+
var extractUuidFromUrl = (url) => {
|
|
1306
|
+
const pattern = /\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:\.[a-z]+)?(?:\?|$)/i;
|
|
1307
|
+
const match = pattern.exec(url);
|
|
1308
|
+
return match ? match[1] : null;
|
|
1309
|
+
};
|
|
1310
|
+
var PlannerMemory = class {
|
|
1311
|
+
taskDescription = "";
|
|
1312
|
+
todos = [];
|
|
1313
|
+
history = [];
|
|
1314
|
+
taskExecutionSummary = "";
|
|
1315
|
+
todoExecutionSummaries = {};
|
|
1316
|
+
setTask(taskDescription, todos) {
|
|
1317
|
+
this.taskDescription = taskDescription;
|
|
1318
|
+
this.todos = todos.map(
|
|
1319
|
+
(todo) => typeof todo === "string" ? { description: todo, status: "pending" } : todo
|
|
1320
|
+
);
|
|
1321
|
+
}
|
|
1322
|
+
getCurrentTodo() {
|
|
1323
|
+
for (let i = 0; i < this.todos.length; i++) {
|
|
1324
|
+
const todo = this.todos[i];
|
|
1325
|
+
if (todo.status === "pending" || todo.status === "in_progress") {
|
|
1326
|
+
return { todo, index: i };
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
return null;
|
|
1330
|
+
}
|
|
1331
|
+
updateTodo(index, status, summary) {
|
|
1332
|
+
if (index < 0 || index >= this.todos.length) return;
|
|
1333
|
+
this.todos[index].status = status;
|
|
1334
|
+
if (summary) {
|
|
1335
|
+
this.todoExecutionSummaries[index] = summary;
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
addHistory(todoIndex, actions, summary, completed = false) {
|
|
1339
|
+
if (todoIndex < 0 || todoIndex >= this.todos.length) return;
|
|
1340
|
+
this.history.push({
|
|
1341
|
+
todo_index: todoIndex,
|
|
1342
|
+
todo: this.todos[todoIndex].description,
|
|
1343
|
+
actions,
|
|
1344
|
+
summary,
|
|
1345
|
+
completed
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
getContext() {
|
|
1349
|
+
return {
|
|
1350
|
+
task_description: this.taskDescription,
|
|
1351
|
+
todos: this.todos.map((todo, index) => ({
|
|
1352
|
+
index,
|
|
1353
|
+
description: todo.description,
|
|
1354
|
+
status: todo.status
|
|
1355
|
+
})),
|
|
1356
|
+
history: this.history.map((history) => ({
|
|
1357
|
+
todo_index: history.todo_index,
|
|
1358
|
+
todo: history.todo,
|
|
1359
|
+
action_count: history.actions.length,
|
|
1360
|
+
summary: history.summary,
|
|
1361
|
+
completed: history.completed
|
|
1362
|
+
})),
|
|
1363
|
+
task_execution_summary: this.taskExecutionSummary,
|
|
1364
|
+
todo_execution_summaries: this.todoExecutionSummaries
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
getTodoStatusSummary() {
|
|
1368
|
+
const summary = {
|
|
1369
|
+
pending: 0,
|
|
1370
|
+
in_progress: 0,
|
|
1371
|
+
completed: 0,
|
|
1372
|
+
skipped: 0,
|
|
1373
|
+
blocked: 0
|
|
1374
|
+
};
|
|
1375
|
+
for (const todo of this.todos) {
|
|
1376
|
+
summary[todo.status] = (summary[todo.status] ?? 0) + 1;
|
|
1377
|
+
}
|
|
1378
|
+
return summary;
|
|
1379
|
+
}
|
|
1380
|
+
appendTodo(description) {
|
|
1381
|
+
this.todos.push({ description, status: "pending" });
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
var Planner = class {
|
|
1385
|
+
constructor(client, apiKey, baseUrl) {
|
|
1386
|
+
this.apiKey = apiKey;
|
|
1387
|
+
this.baseUrl = baseUrl;
|
|
1388
|
+
this.client = client;
|
|
1389
|
+
}
|
|
1390
|
+
client;
|
|
1391
|
+
ownsClient = false;
|
|
1392
|
+
ensureClient() {
|
|
1393
|
+
if (!this.client) {
|
|
1394
|
+
this.client = new Client(this.baseUrl, this.apiKey);
|
|
1395
|
+
this.ownsClient = true;
|
|
1396
|
+
}
|
|
1397
|
+
return this.client;
|
|
1398
|
+
}
|
|
1399
|
+
getClient() {
|
|
1400
|
+
return this.ensureClient();
|
|
1401
|
+
}
|
|
1402
|
+
async close() {
|
|
1403
|
+
if (!this.ownsClient || !this.client) return;
|
|
1404
|
+
const closable = this.client;
|
|
1405
|
+
if (typeof closable.close === "function") {
|
|
1406
|
+
await closable.close();
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
extractMemoryData(memory, context, todoIndex) {
|
|
1410
|
+
if (memory && todoIndex !== void 0) {
|
|
1411
|
+
const taskDescription = memory.taskDescription;
|
|
1412
|
+
const todos = memory.todos.map((todo, index) => ({
|
|
1413
|
+
index,
|
|
1414
|
+
description: todo.description,
|
|
1415
|
+
status: todo.status,
|
|
1416
|
+
execution_summary: memory.todoExecutionSummaries[index] ?? void 0
|
|
1417
|
+
}));
|
|
1418
|
+
const history = memory.history.map((history2) => ({
|
|
1419
|
+
todo_index: history2.todo_index,
|
|
1420
|
+
todo_description: history2.todo,
|
|
1421
|
+
action_count: history2.actions.length,
|
|
1422
|
+
summary: history2.summary ?? void 0,
|
|
1423
|
+
completed: history2.completed
|
|
1424
|
+
}));
|
|
1425
|
+
const taskExecutionSummary = memory.taskExecutionSummary || void 0;
|
|
1426
|
+
const overallTodo = memory.todos[todoIndex] ? memory.todos[todoIndex].description : "";
|
|
1427
|
+
return {
|
|
1428
|
+
taskDescription,
|
|
1429
|
+
todos,
|
|
1430
|
+
history,
|
|
1431
|
+
taskExecutionSummary,
|
|
1432
|
+
overallTodo
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
const rawTodos = context.todos;
|
|
1436
|
+
const rawHistory = context.history;
|
|
1437
|
+
return {
|
|
1438
|
+
taskDescription: context.task_description ?? "",
|
|
1439
|
+
todos: Array.isArray(rawTodos) ? rawTodos : [],
|
|
1440
|
+
history: Array.isArray(rawHistory) ? rawHistory : [],
|
|
1441
|
+
taskExecutionSummary: void 0,
|
|
1442
|
+
overallTodo: context.current_todo ?? ""
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
extractJsonString(text) {
|
|
1446
|
+
const start = text.indexOf("{");
|
|
1447
|
+
const end = text.lastIndexOf("}") + 1;
|
|
1448
|
+
if (start < 0 || end <= start) return "";
|
|
1449
|
+
return text.slice(start, end);
|
|
1450
|
+
}
|
|
1451
|
+
parsePlannerOutput(response) {
|
|
1452
|
+
try {
|
|
1453
|
+
const jsonResponse = this.extractJsonString(response);
|
|
1454
|
+
const data = JSON.parse(jsonResponse);
|
|
1455
|
+
return {
|
|
1456
|
+
instruction: data.subtask ?? data.instruction ?? "",
|
|
1457
|
+
reasoning: data.reasoning ?? "",
|
|
1458
|
+
subtodos: data.subtodos ?? []
|
|
1459
|
+
};
|
|
1460
|
+
} catch {
|
|
1461
|
+
return {
|
|
1462
|
+
instruction: "",
|
|
1463
|
+
reasoning: "Failed to parse structured response",
|
|
1464
|
+
subtodos: []
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
parseReflectionOutput(response) {
|
|
1469
|
+
try {
|
|
1470
|
+
const jsonResponse = this.extractJsonString(response);
|
|
1471
|
+
const data = JSON.parse(jsonResponse);
|
|
1472
|
+
const success = data.success === "yes";
|
|
1473
|
+
const newSubtask = (data.subtask_instruction ?? "").trim();
|
|
1474
|
+
const continueCurrent = !success && !newSubtask;
|
|
1475
|
+
return {
|
|
1476
|
+
continue_current: continueCurrent,
|
|
1477
|
+
new_instruction: newSubtask || null,
|
|
1478
|
+
reasoning: data.reflection ?? data.reasoning ?? "",
|
|
1479
|
+
success_assessment: success
|
|
1480
|
+
};
|
|
1481
|
+
} catch {
|
|
1482
|
+
return {
|
|
1483
|
+
continue_current: true,
|
|
1484
|
+
new_instruction: null,
|
|
1485
|
+
reasoning: "Failed to parse reflection response, continuing current approach",
|
|
1486
|
+
success_assessment: false
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
formatExecutionNotes(context) {
|
|
1491
|
+
const history = context.history;
|
|
1492
|
+
if (!history?.length) return "";
|
|
1493
|
+
const parts = [];
|
|
1494
|
+
for (const item of history) {
|
|
1495
|
+
parts.push(
|
|
1496
|
+
`Todo ${item.todo_index}: ${item.action_count} actions, completed: ${item.completed}`
|
|
1497
|
+
);
|
|
1498
|
+
if (item.summary) {
|
|
1499
|
+
parts.push(`Summary: ${item.summary}`);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
return parts.join("\n");
|
|
1503
|
+
}
|
|
1504
|
+
async ensureScreenshotUuid(screenshot) {
|
|
1505
|
+
if (!screenshot) return { uuid: void 0, url: void 0 };
|
|
1506
|
+
if (typeof screenshot === "string") {
|
|
1507
|
+
const uuid = extractUuidFromUrl(screenshot);
|
|
1508
|
+
return { uuid: uuid ?? void 0, url: screenshot };
|
|
1509
|
+
}
|
|
1510
|
+
const client = this.ensureClient();
|
|
1511
|
+
const upload = await client.putS3PresignedUrl(screenshot);
|
|
1512
|
+
return { uuid: upload.uuid, url: upload.download_url };
|
|
1513
|
+
}
|
|
1514
|
+
async initialPlan(todo, context, screenshot, memory, todoIndex) {
|
|
1515
|
+
const client = this.ensureClient();
|
|
1516
|
+
const { uuid } = await this.ensureScreenshotUuid(screenshot);
|
|
1517
|
+
const { taskDescription, todos, history, taskExecutionSummary } = this.extractMemoryData(memory, context, todoIndex);
|
|
1518
|
+
const response = await client.callWorker({
|
|
1519
|
+
workerId: "oagi_first",
|
|
1520
|
+
overallTodo: todo,
|
|
1521
|
+
taskDescription,
|
|
1522
|
+
todos,
|
|
1523
|
+
history,
|
|
1524
|
+
currentTodoIndex: todoIndex,
|
|
1525
|
+
taskExecutionSummary,
|
|
1526
|
+
currentScreenshot: uuid
|
|
1527
|
+
});
|
|
1528
|
+
return {
|
|
1529
|
+
output: this.parsePlannerOutput(response.response),
|
|
1530
|
+
requestId: response.request_id
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1533
|
+
async reflect(actions, context, screenshot, memory, todoIndex, currentInstruction, reflectionInterval = DEFAULT_REFLECTION_INTERVAL) {
|
|
1534
|
+
const client = this.ensureClient();
|
|
1535
|
+
const { uuid } = await this.ensureScreenshotUuid(screenshot);
|
|
1536
|
+
const {
|
|
1537
|
+
taskDescription,
|
|
1538
|
+
todos,
|
|
1539
|
+
history,
|
|
1540
|
+
taskExecutionSummary,
|
|
1541
|
+
overallTodo
|
|
1542
|
+
} = this.extractMemoryData(memory, context, todoIndex);
|
|
1543
|
+
const windowActions = actions.slice(-reflectionInterval);
|
|
1544
|
+
const windowSteps = windowActions.map((action, index) => ({
|
|
1545
|
+
step_number: index + 1,
|
|
1546
|
+
action_type: action.action_type,
|
|
1547
|
+
target: action.target ?? "",
|
|
1548
|
+
reasoning: action.reasoning ?? ""
|
|
1549
|
+
}));
|
|
1550
|
+
const windowScreenshots = windowActions.map((action) => action.screenshot_uuid).filter(Boolean);
|
|
1551
|
+
const priorNotes = this.formatExecutionNotes(context);
|
|
1552
|
+
const response = await client.callWorker({
|
|
1553
|
+
workerId: "oagi_follow",
|
|
1554
|
+
overallTodo,
|
|
1555
|
+
taskDescription,
|
|
1556
|
+
todos,
|
|
1557
|
+
history,
|
|
1558
|
+
currentTodoIndex: todoIndex,
|
|
1559
|
+
taskExecutionSummary,
|
|
1560
|
+
currentSubtaskInstruction: currentInstruction ?? "",
|
|
1561
|
+
windowSteps,
|
|
1562
|
+
windowScreenshots,
|
|
1563
|
+
resultScreenshot: uuid,
|
|
1564
|
+
priorNotes
|
|
1565
|
+
});
|
|
1566
|
+
return {
|
|
1567
|
+
output: this.parseReflectionOutput(response.response),
|
|
1568
|
+
requestId: response.request_id
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
async summarize(_executionHistory, context, memory, todoIndex) {
|
|
1572
|
+
const client = this.ensureClient();
|
|
1573
|
+
const {
|
|
1574
|
+
taskDescription,
|
|
1575
|
+
todos,
|
|
1576
|
+
history,
|
|
1577
|
+
taskExecutionSummary,
|
|
1578
|
+
overallTodo
|
|
1579
|
+
} = this.extractMemoryData(memory, context, todoIndex);
|
|
1580
|
+
const latestTodoSummary = memory && todoIndex !== void 0 ? memory.todoExecutionSummaries[todoIndex] : "";
|
|
1581
|
+
const response = await client.callWorker({
|
|
1582
|
+
workerId: "oagi_task_summary",
|
|
1583
|
+
overallTodo,
|
|
1584
|
+
taskDescription,
|
|
1585
|
+
todos,
|
|
1586
|
+
history,
|
|
1587
|
+
currentTodoIndex: todoIndex,
|
|
1588
|
+
taskExecutionSummary,
|
|
1589
|
+
latestTodoSummary
|
|
1590
|
+
});
|
|
1591
|
+
try {
|
|
1592
|
+
const parsed = JSON.parse(response.response);
|
|
1593
|
+
return {
|
|
1594
|
+
summary: parsed.task_summary ?? response.response,
|
|
1595
|
+
requestId: response.request_id
|
|
1596
|
+
};
|
|
1597
|
+
} catch {
|
|
1598
|
+
return { summary: response.response, requestId: response.request_id };
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
var TaskeeAgent = class {
|
|
1603
|
+
apiKey;
|
|
1604
|
+
baseUrl;
|
|
1605
|
+
model;
|
|
1606
|
+
maxSteps;
|
|
1607
|
+
reflectionInterval;
|
|
1608
|
+
temperature;
|
|
1609
|
+
planner;
|
|
1610
|
+
externalMemory;
|
|
1611
|
+
todoIndex;
|
|
1612
|
+
stepObserver;
|
|
1613
|
+
stepDelay;
|
|
1614
|
+
actor;
|
|
1615
|
+
currentTodo = "";
|
|
1616
|
+
currentInstruction = "";
|
|
1617
|
+
actions = [];
|
|
1618
|
+
totalActions = 0;
|
|
1619
|
+
sinceReflection = 0;
|
|
1620
|
+
success = false;
|
|
1621
|
+
constructor(apiKey, baseUrl, model = MODEL_ACTOR, maxSteps = DEFAULT_MAX_STEPS, reflectionInterval = DEFAULT_REFLECTION_INTERVAL, temperature = DEFAULT_TEMPERATURE, planner, externalMemory, todoIndex, stepObserver, stepDelay = DEFAULT_STEP_DELAY) {
|
|
1622
|
+
this.apiKey = apiKey;
|
|
1623
|
+
this.baseUrl = baseUrl;
|
|
1624
|
+
this.model = model;
|
|
1625
|
+
this.maxSteps = maxSteps;
|
|
1626
|
+
this.reflectionInterval = reflectionInterval;
|
|
1627
|
+
this.temperature = temperature;
|
|
1628
|
+
this.planner = planner ?? new Planner(void 0, apiKey, baseUrl);
|
|
1629
|
+
this.externalMemory = externalMemory;
|
|
1630
|
+
this.todoIndex = todoIndex;
|
|
1631
|
+
this.stepObserver = stepObserver;
|
|
1632
|
+
this.stepDelay = stepDelay;
|
|
1633
|
+
}
|
|
1634
|
+
async execute(instruction, actionHandler, imageProvider) {
|
|
1635
|
+
resetHandler2(actionHandler);
|
|
1636
|
+
this.currentTodo = instruction;
|
|
1637
|
+
this.actions = [];
|
|
1638
|
+
this.totalActions = 0;
|
|
1639
|
+
this.sinceReflection = 0;
|
|
1640
|
+
this.success = false;
|
|
1641
|
+
try {
|
|
1642
|
+
this.actor = new Actor(
|
|
1643
|
+
this.apiKey,
|
|
1644
|
+
this.baseUrl,
|
|
1645
|
+
this.model,
|
|
1646
|
+
this.temperature
|
|
1647
|
+
);
|
|
1648
|
+
await this.initialPlan(imageProvider);
|
|
1649
|
+
this.actor.initTask(this.currentInstruction, this.maxSteps);
|
|
1650
|
+
let remainingSteps = this.maxSteps;
|
|
1651
|
+
while (remainingSteps > 0 && !this.success) {
|
|
1652
|
+
const stepsTaken = await this.executeSubtask(
|
|
1653
|
+
Math.min(this.maxSteps, remainingSteps),
|
|
1654
|
+
actionHandler,
|
|
1655
|
+
imageProvider
|
|
1656
|
+
);
|
|
1657
|
+
remainingSteps -= stepsTaken;
|
|
1658
|
+
if (!this.success && remainingSteps > 0) {
|
|
1659
|
+
const shouldContinue = await this.reflectAndDecide(imageProvider);
|
|
1660
|
+
if (!shouldContinue) {
|
|
1661
|
+
break;
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
await this.generateSummary();
|
|
1666
|
+
return this.success;
|
|
1667
|
+
} catch (err) {
|
|
1668
|
+
logger5.error(`Error executing todo: ${err}`);
|
|
1669
|
+
this.recordAction("error", null, String(err));
|
|
1670
|
+
return false;
|
|
1671
|
+
} finally {
|
|
1672
|
+
this.actor = void 0;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
getContext() {
|
|
1676
|
+
return this.externalMemory ? this.externalMemory.getContext() : {};
|
|
1677
|
+
}
|
|
1678
|
+
recordAction(actionType, target, reasoning, result, screenshotUuid) {
|
|
1679
|
+
this.actions.push({
|
|
1680
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1681
|
+
action_type: actionType,
|
|
1682
|
+
target,
|
|
1683
|
+
reasoning,
|
|
1684
|
+
result,
|
|
1685
|
+
details: {},
|
|
1686
|
+
screenshot_uuid: screenshotUuid ?? void 0
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
async initialPlan(imageProvider) {
|
|
1690
|
+
logger5.info("Generating initial plan for todo");
|
|
1691
|
+
const screenshot = await imageProvider.provide();
|
|
1692
|
+
const context = this.getContext();
|
|
1693
|
+
const { output, requestId } = await this.planner.initialPlan(
|
|
1694
|
+
this.currentTodo,
|
|
1695
|
+
context,
|
|
1696
|
+
screenshot,
|
|
1697
|
+
this.externalMemory,
|
|
1698
|
+
this.todoIndex
|
|
1699
|
+
);
|
|
1700
|
+
this.recordAction("plan", "initial", output.reasoning, output.instruction);
|
|
1701
|
+
if (this.stepObserver) {
|
|
1702
|
+
const event = {
|
|
1703
|
+
type: "plan",
|
|
1704
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1705
|
+
phase: "initial",
|
|
1706
|
+
image: screenshot,
|
|
1707
|
+
reasoning: output.reasoning,
|
|
1708
|
+
result: output.instruction,
|
|
1709
|
+
request_id: requestId ?? void 0
|
|
1710
|
+
};
|
|
1711
|
+
await this.stepObserver.onEvent(event);
|
|
1712
|
+
}
|
|
1713
|
+
this.currentInstruction = output.instruction;
|
|
1714
|
+
logger5.info(`Initial instruction: ${this.currentInstruction}`);
|
|
1715
|
+
}
|
|
1716
|
+
async executeSubtask(maxSteps, actionHandler, imageProvider) {
|
|
1717
|
+
logger5.info(`Executing subtask with max ${maxSteps} steps`);
|
|
1718
|
+
let stepsTaken = 0;
|
|
1719
|
+
const client = this.planner.getClient();
|
|
1720
|
+
for (let stepNum = 0; stepNum < maxSteps; stepNum++) {
|
|
1721
|
+
const screenshot = await imageProvider.provide();
|
|
1722
|
+
let screenshotUuid;
|
|
1723
|
+
let screenshotUrl;
|
|
1724
|
+
try {
|
|
1725
|
+
if (typeof screenshot === "string") {
|
|
1726
|
+
screenshotUuid = extractUuidFromUrl(screenshot) ?? void 0;
|
|
1727
|
+
screenshotUrl = screenshot;
|
|
1728
|
+
} else {
|
|
1729
|
+
const upload = await client.putS3PresignedUrl(screenshot);
|
|
1730
|
+
screenshotUuid = upload.uuid;
|
|
1731
|
+
screenshotUrl = upload.download_url;
|
|
1732
|
+
}
|
|
1733
|
+
} catch (err) {
|
|
1734
|
+
logger5.error(`Error uploading screenshot: ${err}`);
|
|
1735
|
+
this.recordAction("error", "screenshot_upload", String(err));
|
|
1736
|
+
break;
|
|
1737
|
+
}
|
|
1738
|
+
let step;
|
|
1739
|
+
try {
|
|
1740
|
+
step = await this.actor.step(screenshotUrl ?? screenshot, void 0);
|
|
1741
|
+
} catch (err) {
|
|
1742
|
+
logger5.error(`Error getting step from OAGI: ${err}`);
|
|
1743
|
+
this.recordAction(
|
|
1744
|
+
"error",
|
|
1745
|
+
"oagi_step",
|
|
1746
|
+
String(err),
|
|
1747
|
+
null,
|
|
1748
|
+
screenshotUuid
|
|
1749
|
+
);
|
|
1750
|
+
break;
|
|
1751
|
+
}
|
|
1752
|
+
if (step.reason) {
|
|
1753
|
+
logger5.info(`Step ${this.totalActions + 1}: ${step.reason}`);
|
|
1754
|
+
}
|
|
1755
|
+
if (this.stepObserver) {
|
|
1756
|
+
const event = {
|
|
1757
|
+
type: "step",
|
|
1758
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1759
|
+
step_num: this.totalActions + 1,
|
|
1760
|
+
image: screenshot,
|
|
1761
|
+
step,
|
|
1762
|
+
task_id: this.actor.taskId
|
|
1763
|
+
};
|
|
1764
|
+
await this.stepObserver.onEvent(event);
|
|
1765
|
+
}
|
|
1766
|
+
if (step.actions?.length) {
|
|
1767
|
+
logger5.info(`Actions (${step.actions.length}):`);
|
|
1768
|
+
for (const action of step.actions) {
|
|
1769
|
+
const countSuffix = action.count && action.count > 1 ? ` x${action.count}` : "";
|
|
1770
|
+
logger5.info(` [${action.type}] ${action.argument}${countSuffix}`);
|
|
1771
|
+
}
|
|
1772
|
+
for (const action of step.actions) {
|
|
1773
|
+
this.recordAction(
|
|
1774
|
+
action.type,
|
|
1775
|
+
action.argument,
|
|
1776
|
+
step.reason ?? null,
|
|
1777
|
+
null,
|
|
1778
|
+
screenshotUuid
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
let error = null;
|
|
1782
|
+
try {
|
|
1783
|
+
await actionHandler.handle(step.actions);
|
|
1784
|
+
} catch (err) {
|
|
1785
|
+
error = String(err);
|
|
1786
|
+
throw err;
|
|
1787
|
+
} finally {
|
|
1788
|
+
if (this.stepObserver) {
|
|
1789
|
+
const event = {
|
|
1790
|
+
type: "action",
|
|
1791
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1792
|
+
step_num: this.totalActions + 1,
|
|
1793
|
+
actions: step.actions,
|
|
1794
|
+
error: error ?? void 0
|
|
1795
|
+
};
|
|
1796
|
+
await this.stepObserver.onEvent(event);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
this.totalActions += step.actions.length;
|
|
1800
|
+
this.sinceReflection += step.actions.length;
|
|
1801
|
+
}
|
|
1802
|
+
if (this.stepDelay > 0) {
|
|
1803
|
+
await sleep2(this.stepDelay);
|
|
1804
|
+
}
|
|
1805
|
+
stepsTaken += 1;
|
|
1806
|
+
if (step.stop) {
|
|
1807
|
+
logger5.info("OAGI signaled task completion");
|
|
1808
|
+
break;
|
|
1809
|
+
}
|
|
1810
|
+
if (this.sinceReflection >= this.reflectionInterval) {
|
|
1811
|
+
logger5.info("Reflection interval reached");
|
|
1812
|
+
break;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
return stepsTaken;
|
|
1816
|
+
}
|
|
1817
|
+
async reflectAndDecide(imageProvider) {
|
|
1818
|
+
logger5.info("Reflecting on progress");
|
|
1819
|
+
const screenshot = await imageProvider.provide();
|
|
1820
|
+
const context = this.getContext();
|
|
1821
|
+
context.current_todo = this.currentTodo;
|
|
1822
|
+
const recentActions = this.actions.slice(-this.sinceReflection);
|
|
1823
|
+
const { output, requestId } = await this.planner.reflect(
|
|
1824
|
+
recentActions,
|
|
1825
|
+
context,
|
|
1826
|
+
screenshot,
|
|
1827
|
+
this.externalMemory,
|
|
1828
|
+
this.todoIndex,
|
|
1829
|
+
this.currentInstruction,
|
|
1830
|
+
this.reflectionInterval
|
|
1831
|
+
);
|
|
1832
|
+
this.recordAction(
|
|
1833
|
+
"reflect",
|
|
1834
|
+
null,
|
|
1835
|
+
output.reasoning,
|
|
1836
|
+
output.continue_current ? "continue" : "pivot"
|
|
1837
|
+
);
|
|
1838
|
+
if (this.stepObserver) {
|
|
1839
|
+
const decision = output.success_assessment ? "success" : output.continue_current ? "continue" : "pivot";
|
|
1840
|
+
const event = {
|
|
1841
|
+
type: "plan",
|
|
1842
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1843
|
+
phase: "reflection",
|
|
1844
|
+
image: screenshot,
|
|
1845
|
+
reasoning: output.reasoning,
|
|
1846
|
+
result: decision,
|
|
1847
|
+
request_id: requestId ?? void 0
|
|
1848
|
+
};
|
|
1849
|
+
await this.stepObserver.onEvent(event);
|
|
1850
|
+
}
|
|
1851
|
+
if (output.success_assessment) {
|
|
1852
|
+
this.success = true;
|
|
1853
|
+
logger5.info("Reflection indicates task is successful");
|
|
1854
|
+
return false;
|
|
1855
|
+
}
|
|
1856
|
+
this.sinceReflection = 0;
|
|
1857
|
+
if (!output.continue_current && output.new_instruction) {
|
|
1858
|
+
logger5.info(`Pivoting to new instruction: ${output.new_instruction}`);
|
|
1859
|
+
this.currentInstruction = output.new_instruction;
|
|
1860
|
+
await this.actor.initTask(this.currentInstruction, this.maxSteps);
|
|
1861
|
+
return true;
|
|
1862
|
+
}
|
|
1863
|
+
return output.continue_current;
|
|
1864
|
+
}
|
|
1865
|
+
async generateSummary() {
|
|
1866
|
+
logger5.info("Generating execution summary");
|
|
1867
|
+
const context = this.getContext();
|
|
1868
|
+
context.current_todo = this.currentTodo;
|
|
1869
|
+
const { summary, requestId } = await this.planner.summarize(
|
|
1870
|
+
this.actions,
|
|
1871
|
+
context,
|
|
1872
|
+
this.externalMemory,
|
|
1873
|
+
this.todoIndex
|
|
1874
|
+
);
|
|
1875
|
+
this.recordAction("summary", null, summary);
|
|
1876
|
+
if (this.stepObserver) {
|
|
1877
|
+
const event = {
|
|
1878
|
+
type: "plan",
|
|
1879
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1880
|
+
phase: "summary",
|
|
1881
|
+
image: void 0,
|
|
1882
|
+
reasoning: summary,
|
|
1883
|
+
result: void 0,
|
|
1884
|
+
request_id: requestId ?? void 0
|
|
1885
|
+
};
|
|
1886
|
+
await this.stepObserver.onEvent(event);
|
|
1887
|
+
}
|
|
1888
|
+
logger5.info(`Execution summary: ${summary}`);
|
|
1889
|
+
}
|
|
1890
|
+
returnExecutionResults() {
|
|
1891
|
+
let summary = "";
|
|
1892
|
+
for (let i = this.actions.length - 1; i >= 0; i--) {
|
|
1893
|
+
if (this.actions[i].action_type === "summary") {
|
|
1894
|
+
summary = this.actions[i].reasoning ?? "";
|
|
1895
|
+
break;
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
return {
|
|
1899
|
+
success: this.success,
|
|
1900
|
+
actions: this.actions,
|
|
1901
|
+
summary,
|
|
1902
|
+
total_steps: this.totalActions
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
};
|
|
1906
|
+
var TaskerAgent = class {
|
|
1907
|
+
/** Hierarchical agent that manages multi-todo workflows. */
|
|
1908
|
+
apiKey;
|
|
1909
|
+
baseUrl;
|
|
1910
|
+
model;
|
|
1911
|
+
maxSteps;
|
|
1912
|
+
temperature;
|
|
1913
|
+
reflectionInterval;
|
|
1914
|
+
planner;
|
|
1915
|
+
stepObserver;
|
|
1916
|
+
stepDelay;
|
|
1917
|
+
memory = new PlannerMemory();
|
|
1918
|
+
currentTaskeeAgent;
|
|
1919
|
+
constructor(apiKey, baseUrl, model = MODEL_ACTOR, maxSteps = DEFAULT_MAX_STEPS_TASKER, temperature = DEFAULT_TEMPERATURE, reflectionInterval = DEFAULT_REFLECTION_INTERVAL, planner, stepObserver, stepDelay = DEFAULT_STEP_DELAY) {
|
|
1920
|
+
this.apiKey = apiKey;
|
|
1921
|
+
this.baseUrl = baseUrl;
|
|
1922
|
+
this.model = model;
|
|
1923
|
+
this.maxSteps = maxSteps;
|
|
1924
|
+
this.temperature = temperature;
|
|
1925
|
+
this.reflectionInterval = reflectionInterval;
|
|
1926
|
+
this.planner = planner ?? new Planner(void 0, apiKey, baseUrl);
|
|
1927
|
+
this.stepObserver = stepObserver;
|
|
1928
|
+
this.stepDelay = stepDelay;
|
|
1929
|
+
}
|
|
1930
|
+
setTask(task, todos) {
|
|
1931
|
+
this.memory.setTask(task, todos);
|
|
1932
|
+
logger5.info(`Task set with ${todos.length} todos`);
|
|
1933
|
+
}
|
|
1934
|
+
set_task(task, todos) {
|
|
1935
|
+
this.setTask(task, todos);
|
|
1936
|
+
}
|
|
1937
|
+
async execute(_instruction, actionHandler, imageProvider) {
|
|
1938
|
+
resetHandler2(actionHandler);
|
|
1939
|
+
let overallSuccess = true;
|
|
1940
|
+
while (true) {
|
|
1941
|
+
const todoInfo = this.prepare();
|
|
1942
|
+
if (!todoInfo) {
|
|
1943
|
+
logger5.info("No more todos to execute");
|
|
1944
|
+
break;
|
|
1945
|
+
}
|
|
1946
|
+
const { todo, index } = todoInfo;
|
|
1947
|
+
logger5.info(`Executing todo ${index}: ${todo.description}`);
|
|
1948
|
+
if (this.stepObserver) {
|
|
1949
|
+
const event = {
|
|
1950
|
+
type: "split",
|
|
1951
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1952
|
+
label: `Start of todo ${index + 1}: ${todo.description}`
|
|
1953
|
+
};
|
|
1954
|
+
await this.stepObserver.onEvent(event);
|
|
1955
|
+
}
|
|
1956
|
+
const success = await this.executeTodo(
|
|
1957
|
+
index,
|
|
1958
|
+
actionHandler,
|
|
1959
|
+
imageProvider
|
|
1960
|
+
);
|
|
1961
|
+
if (this.stepObserver) {
|
|
1962
|
+
const event = {
|
|
1963
|
+
type: "split",
|
|
1964
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
1965
|
+
label: `End of todo ${index + 1}: ${todo.description}`
|
|
1966
|
+
};
|
|
1967
|
+
await this.stepObserver.onEvent(event);
|
|
1968
|
+
}
|
|
1969
|
+
if (!success) {
|
|
1970
|
+
logger5.warn(`Todo ${index} failed`);
|
|
1971
|
+
overallSuccess = false;
|
|
1972
|
+
const currentStatus = this.memory.todos[index]?.status;
|
|
1973
|
+
if (currentStatus === "in_progress") {
|
|
1974
|
+
logger5.error("Todo failed with exception, stopping execution");
|
|
1975
|
+
break;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
this.updateTaskSummary();
|
|
1979
|
+
}
|
|
1980
|
+
const statusSummary = this.memory.getTodoStatusSummary();
|
|
1981
|
+
logger5.info(
|
|
1982
|
+
`Workflow complete. Status summary: ${JSON.stringify(statusSummary)}`
|
|
1983
|
+
);
|
|
1984
|
+
return overallSuccess;
|
|
1985
|
+
}
|
|
1986
|
+
prepare() {
|
|
1987
|
+
const current = this.memory.getCurrentTodo();
|
|
1988
|
+
if (!current) return null;
|
|
1989
|
+
this.currentTaskeeAgent = new TaskeeAgent(
|
|
1990
|
+
this.apiKey,
|
|
1991
|
+
this.baseUrl,
|
|
1992
|
+
this.model,
|
|
1993
|
+
this.maxSteps,
|
|
1994
|
+
this.reflectionInterval,
|
|
1995
|
+
this.temperature,
|
|
1996
|
+
this.planner,
|
|
1997
|
+
this.memory,
|
|
1998
|
+
current.index,
|
|
1999
|
+
this.stepObserver,
|
|
2000
|
+
this.stepDelay
|
|
2001
|
+
);
|
|
2002
|
+
if (current.todo.status === "pending") {
|
|
2003
|
+
this.memory.updateTodo(current.index, "in_progress");
|
|
2004
|
+
}
|
|
2005
|
+
logger5.info(`Prepared taskee agent for todo ${current.index}`);
|
|
2006
|
+
return current;
|
|
2007
|
+
}
|
|
2008
|
+
async executeTodo(todoIndex, actionHandler, imageProvider) {
|
|
2009
|
+
if (!this.currentTaskeeAgent || todoIndex < 0) {
|
|
2010
|
+
logger5.error("No taskee agent prepared");
|
|
2011
|
+
return false;
|
|
2012
|
+
}
|
|
2013
|
+
const todo = this.memory.todos[todoIndex];
|
|
2014
|
+
try {
|
|
2015
|
+
const success = await this.currentTaskeeAgent.execute(
|
|
2016
|
+
todo.description,
|
|
2017
|
+
actionHandler,
|
|
2018
|
+
imageProvider
|
|
2019
|
+
);
|
|
2020
|
+
const results = this.currentTaskeeAgent.returnExecutionResults();
|
|
2021
|
+
this.updateMemoryFromExecution(todoIndex, results, success);
|
|
2022
|
+
return success;
|
|
2023
|
+
} catch (err) {
|
|
2024
|
+
logger5.error(`Error executing todo ${todoIndex}: ${err}`);
|
|
2025
|
+
this.memory.updateTodo(
|
|
2026
|
+
todoIndex,
|
|
2027
|
+
"in_progress",
|
|
2028
|
+
`Execution failed: ${String(err)}`
|
|
2029
|
+
);
|
|
2030
|
+
return false;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
updateMemoryFromExecution(todoIndex, results, success) {
|
|
2034
|
+
const status = success ? "completed" : "in_progress";
|
|
2035
|
+
this.memory.updateTodo(todoIndex, status, results.summary);
|
|
2036
|
+
this.memory.addHistory(
|
|
2037
|
+
todoIndex,
|
|
2038
|
+
results.actions,
|
|
2039
|
+
results.summary,
|
|
2040
|
+
success
|
|
2041
|
+
);
|
|
2042
|
+
if (success) {
|
|
2043
|
+
const summaryLine = `- Completed todo ${todoIndex}: ${results.summary}`;
|
|
2044
|
+
this.memory.taskExecutionSummary = this.memory.taskExecutionSummary ? `${this.memory.taskExecutionSummary}
|
|
2045
|
+
${summaryLine}` : summaryLine;
|
|
2046
|
+
}
|
|
2047
|
+
logger5.info(
|
|
2048
|
+
`Updated memory for todo ${todoIndex}: status=${status}, actions=${results.actions.length}`
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
2051
|
+
updateTaskSummary() {
|
|
2052
|
+
const statusSummary = this.memory.getTodoStatusSummary();
|
|
2053
|
+
const completed = statusSummary.completed ?? 0;
|
|
2054
|
+
const total = this.memory.todos.length;
|
|
2055
|
+
const summaryParts = [`Progress: ${completed}/${total} todos completed`];
|
|
2056
|
+
const recentHistory = this.memory.history.slice(-3);
|
|
2057
|
+
for (const history of recentHistory) {
|
|
2058
|
+
if (history.completed && history.summary) {
|
|
2059
|
+
summaryParts.push(
|
|
2060
|
+
`- Todo ${history.todo_index}: ${history.summary.slice(0, 100)}`
|
|
2061
|
+
);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
this.memory.taskExecutionSummary = summaryParts.join("\n");
|
|
2065
|
+
}
|
|
2066
|
+
getMemory() {
|
|
2067
|
+
return this.memory;
|
|
2068
|
+
}
|
|
2069
|
+
appendTodo(description) {
|
|
2070
|
+
this.memory.appendTodo(description);
|
|
2071
|
+
logger5.info(`Appended new todo: ${description}`);
|
|
2072
|
+
}
|
|
2073
|
+
};
|
|
2074
|
+
|
|
1234
2075
|
// src/agent/registry.ts
|
|
1235
2076
|
var agentRegistry = {};
|
|
1236
2077
|
var asyncAgentRegister = (mode) => {
|
|
@@ -1271,7 +2112,7 @@ var createAgent = (mode, options = {}) => {
|
|
|
1271
2112
|
asyncAgentRegister("actor")((options = {}) => {
|
|
1272
2113
|
const {
|
|
1273
2114
|
apiKey,
|
|
1274
|
-
|
|
2115
|
+
baseURL,
|
|
1275
2116
|
model = MODEL_ACTOR,
|
|
1276
2117
|
maxSteps = DEFAULT_MAX_STEPS,
|
|
1277
2118
|
temperature = DEFAULT_TEMPERATURE_LOW,
|
|
@@ -1280,7 +2121,7 @@ asyncAgentRegister("actor")((options = {}) => {
|
|
|
1280
2121
|
} = options;
|
|
1281
2122
|
return new DefaultAgent(
|
|
1282
2123
|
apiKey,
|
|
1283
|
-
|
|
2124
|
+
baseURL,
|
|
1284
2125
|
model,
|
|
1285
2126
|
maxSteps,
|
|
1286
2127
|
temperature,
|
|
@@ -1291,7 +2132,7 @@ asyncAgentRegister("actor")((options = {}) => {
|
|
|
1291
2132
|
asyncAgentRegister("thinker")((options = {}) => {
|
|
1292
2133
|
const {
|
|
1293
2134
|
apiKey,
|
|
1294
|
-
|
|
2135
|
+
baseURL,
|
|
1295
2136
|
model = MODEL_THINKER,
|
|
1296
2137
|
maxSteps = DEFAULT_MAX_STEPS_THINKER,
|
|
1297
2138
|
temperature = DEFAULT_TEMPERATURE_LOW,
|
|
@@ -1300,7 +2141,7 @@ asyncAgentRegister("thinker")((options = {}) => {
|
|
|
1300
2141
|
} = options;
|
|
1301
2142
|
return new DefaultAgent(
|
|
1302
2143
|
apiKey,
|
|
1303
|
-
|
|
2144
|
+
baseURL,
|
|
1304
2145
|
model,
|
|
1305
2146
|
maxSteps,
|
|
1306
2147
|
temperature,
|
|
@@ -1308,11 +2149,119 @@ asyncAgentRegister("thinker")((options = {}) => {
|
|
|
1308
2149
|
stepDelay
|
|
1309
2150
|
);
|
|
1310
2151
|
});
|
|
2152
|
+
asyncAgentRegister("tasker")((options = {}) => {
|
|
2153
|
+
const {
|
|
2154
|
+
apiKey,
|
|
2155
|
+
baseURL,
|
|
2156
|
+
model = MODEL_ACTOR,
|
|
2157
|
+
maxSteps = DEFAULT_MAX_STEPS_TASKER,
|
|
2158
|
+
temperature = DEFAULT_TEMPERATURE,
|
|
2159
|
+
reflectionInterval = DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
2160
|
+
stepObserver,
|
|
2161
|
+
stepDelay = DEFAULT_STEP_DELAY
|
|
2162
|
+
} = options;
|
|
2163
|
+
return new TaskerAgent(
|
|
2164
|
+
apiKey,
|
|
2165
|
+
baseURL,
|
|
2166
|
+
model,
|
|
2167
|
+
maxSteps,
|
|
2168
|
+
temperature,
|
|
2169
|
+
reflectionInterval,
|
|
2170
|
+
void 0,
|
|
2171
|
+
stepObserver ?? void 0,
|
|
2172
|
+
stepDelay
|
|
2173
|
+
);
|
|
2174
|
+
});
|
|
2175
|
+
asyncAgentRegister("tasker:cvs_appointment")(
|
|
2176
|
+
(options = {}) => {
|
|
2177
|
+
const {
|
|
2178
|
+
apiKey,
|
|
2179
|
+
baseURL,
|
|
2180
|
+
model = MODEL_ACTOR,
|
|
2181
|
+
maxSteps = DEFAULT_MAX_STEPS_TASKER,
|
|
2182
|
+
temperature = DEFAULT_TEMPERATURE,
|
|
2183
|
+
reflectionInterval = DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
2184
|
+
stepObserver,
|
|
2185
|
+
stepDelay = DEFAULT_STEP_DELAY
|
|
2186
|
+
} = options;
|
|
2187
|
+
const tasker = new TaskerAgent(
|
|
2188
|
+
apiKey,
|
|
2189
|
+
baseURL,
|
|
2190
|
+
model,
|
|
2191
|
+
maxSteps,
|
|
2192
|
+
temperature,
|
|
2193
|
+
reflectionInterval,
|
|
2194
|
+
void 0,
|
|
2195
|
+
stepObserver ?? void 0,
|
|
2196
|
+
stepDelay
|
|
2197
|
+
);
|
|
2198
|
+
const firstName = "First";
|
|
2199
|
+
const lastName = "Last";
|
|
2200
|
+
const email = "user@example.com";
|
|
2201
|
+
const birthday = "01-01-1990";
|
|
2202
|
+
const zipCode = "00000";
|
|
2203
|
+
const [month, day, year] = birthday.split("-");
|
|
2204
|
+
const instruction = `Schedule an appointment at CVS for ${firstName} ${lastName} with email ${email} and birthday ${birthday}`;
|
|
2205
|
+
const todos = [
|
|
2206
|
+
"Open a new tab, go to www.cvs.com, type 'flu shot' in the search bar and press enter, wait for the page to load, then click on the button of Schedule vaccinations on the top of the page",
|
|
2207
|
+
`Enter the first name '${firstName}', last name '${lastName}', and email '${email}' in the form. Do not use any suggested autofills. Make sure the mobile phone number is empty.`,
|
|
2208
|
+
"Slightly scroll down to see the date of birth, enter Month '" + month + "', Day '" + day + "', and Year '" + year + "' in the form",
|
|
2209
|
+
"Click on 'Continue as guest' button, wait for the page to load with wait, click on 'Add vaccines' button, select 'Flu' and click on 'Add vaccines'",
|
|
2210
|
+
"Click on 'next' to enter the page with recommendation vaccines, then click on 'next' again, until on the page of entering zip code, enter '" + zipCode + "', select the first option from the dropdown menu, and click on 'Search'"
|
|
2211
|
+
];
|
|
2212
|
+
tasker.setTask(instruction, todos);
|
|
2213
|
+
return tasker;
|
|
2214
|
+
}
|
|
2215
|
+
);
|
|
2216
|
+
asyncAgentRegister("tasker:software_qa")(
|
|
2217
|
+
(options = {}) => {
|
|
2218
|
+
const {
|
|
2219
|
+
apiKey,
|
|
2220
|
+
baseURL,
|
|
2221
|
+
model = MODEL_ACTOR,
|
|
2222
|
+
maxSteps = DEFAULT_MAX_STEPS_TASKER,
|
|
2223
|
+
temperature = DEFAULT_TEMPERATURE,
|
|
2224
|
+
reflectionInterval = DEFAULT_REFLECTION_INTERVAL_TASKER,
|
|
2225
|
+
stepObserver,
|
|
2226
|
+
stepDelay = DEFAULT_STEP_DELAY
|
|
2227
|
+
} = options;
|
|
2228
|
+
const tasker = new TaskerAgent(
|
|
2229
|
+
apiKey,
|
|
2230
|
+
baseURL,
|
|
2231
|
+
model,
|
|
2232
|
+
maxSteps,
|
|
2233
|
+
temperature,
|
|
2234
|
+
reflectionInterval,
|
|
2235
|
+
void 0,
|
|
2236
|
+
stepObserver ?? void 0,
|
|
2237
|
+
stepDelay
|
|
2238
|
+
);
|
|
2239
|
+
const instruction = "QA: click through every sidebar button in the Nuclear Player UI";
|
|
2240
|
+
const todos = [
|
|
2241
|
+
"Click on 'Dashboard' in the left sidebar",
|
|
2242
|
+
"Click on 'Downloads' in the left sidebar",
|
|
2243
|
+
"Click on 'Lyrics' in the left sidebar",
|
|
2244
|
+
"Click on 'Plugins' in the left sidebar",
|
|
2245
|
+
"Click on 'Search Results' in the left sidebar",
|
|
2246
|
+
"Click on 'Settings' in the left sidebar",
|
|
2247
|
+
"Click on 'Equalizer' in the left sidebar",
|
|
2248
|
+
"Click on 'Visualizer' in the left sidebar",
|
|
2249
|
+
"Click on 'Listening History' in the left sidebar",
|
|
2250
|
+
"Click on 'Favorite Albums' in the left sidebar",
|
|
2251
|
+
"Click on 'Favorite Tracks' in the left sidebar",
|
|
2252
|
+
"Click on 'Favorite Artists' in the left sidebar",
|
|
2253
|
+
"Click on 'Local Library' in the left sidebar",
|
|
2254
|
+
"Click on 'Playlists' in the left sidebar"
|
|
2255
|
+
];
|
|
2256
|
+
tasker.setTask(instruction, todos);
|
|
2257
|
+
return tasker;
|
|
2258
|
+
}
|
|
2259
|
+
);
|
|
1311
2260
|
|
|
1312
2261
|
// src/handler.ts
|
|
1313
2262
|
var import_robotjs = __toESM(require("robotjs"), 1);
|
|
1314
2263
|
var import_sharp = __toESM(require("sharp"), 1);
|
|
1315
|
-
var
|
|
2264
|
+
var sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
1316
2265
|
var toSharpKernel = (resample) => {
|
|
1317
2266
|
switch (resample) {
|
|
1318
2267
|
case "NEAREST":
|
|
@@ -1473,7 +2422,7 @@ var DefaultActionHandler = class {
|
|
|
1473
2422
|
import_robotjs.default.moveMouse(p1.x, p1.y);
|
|
1474
2423
|
import_robotjs.default.mouseToggle("down", "left");
|
|
1475
2424
|
import_robotjs.default.dragMouse(p2.x, p2.y);
|
|
1476
|
-
await
|
|
2425
|
+
await sleep3(this.#cfg.dragDurationMs);
|
|
1477
2426
|
import_robotjs.default.mouseToggle("up", "left");
|
|
1478
2427
|
return;
|
|
1479
2428
|
}
|
|
@@ -1493,7 +2442,7 @@ var DefaultActionHandler = class {
|
|
|
1493
2442
|
if (!last) return;
|
|
1494
2443
|
const modifiers = keys.slice(0, -1);
|
|
1495
2444
|
import_robotjs.default.keyTap(last, modifiers.length ? modifiers : []);
|
|
1496
|
-
await
|
|
2445
|
+
await sleep3(this.#cfg.hotkeyDelayMs);
|
|
1497
2446
|
return;
|
|
1498
2447
|
}
|
|
1499
2448
|
case "type": {
|
|
@@ -1513,7 +2462,7 @@ var DefaultActionHandler = class {
|
|
|
1513
2462
|
return;
|
|
1514
2463
|
}
|
|
1515
2464
|
case "wait": {
|
|
1516
|
-
await
|
|
2465
|
+
await sleep3(this.#cfg.waitDurationMs);
|
|
1517
2466
|
return;
|
|
1518
2467
|
}
|
|
1519
2468
|
case "finish": {
|
|
@@ -1603,7 +2552,7 @@ var StepTracker = class extends StepObserver {
|
|
|
1603
2552
|
|
|
1604
2553
|
// src/cli/agent.ts
|
|
1605
2554
|
var import_node_mac_permissions = __toESM(require("@hurdlegroup/node-mac-permissions"), 1);
|
|
1606
|
-
var
|
|
2555
|
+
var logger6 = logger_default("cli.agent");
|
|
1607
2556
|
var checkPermissions = async () => {
|
|
1608
2557
|
if (process.platform !== "darwin") {
|
|
1609
2558
|
process.stdout.write(
|
|
@@ -1650,7 +2599,7 @@ Get your API key at ${API_KEY_HELP_URL}
|
|
|
1650
2599
|
process.exitCode = 1;
|
|
1651
2600
|
return;
|
|
1652
2601
|
}
|
|
1653
|
-
const
|
|
2602
|
+
const baseURL = opts.oagiBaseUrl ?? process.env.OAGI_BASE_URL ?? DEFAULT_BASE_URL;
|
|
1654
2603
|
const mode = opts.mode ?? MODE_ACTOR;
|
|
1655
2604
|
const stepDelay = opts.stepDelay ?? DEFAULT_STEP_DELAY;
|
|
1656
2605
|
const exportFormat = opts.export;
|
|
@@ -1659,7 +2608,7 @@ Get your API key at ${API_KEY_HELP_URL}
|
|
|
1659
2608
|
const agentObserver = exportFormat ? new AsyncAgentObserver() : null;
|
|
1660
2609
|
const createOpts = {
|
|
1661
2610
|
apiKey,
|
|
1662
|
-
|
|
2611
|
+
baseURL,
|
|
1663
2612
|
stepObserver: stepTracker.chain(agentObserver),
|
|
1664
2613
|
stepDelay
|
|
1665
2614
|
};
|
|
@@ -1717,7 +2666,7 @@ If you're using pnpm and robotjs is installed, you may need to run: pnpm approve
|
|
|
1717
2666
|
if (interrupted) {
|
|
1718
2667
|
process.exitCode = 130;
|
|
1719
2668
|
} else {
|
|
1720
|
-
|
|
2669
|
+
logger6.error(`Error during agent execution: ${String(err)}`);
|
|
1721
2670
|
process.exitCode = 1;
|
|
1722
2671
|
}
|
|
1723
2672
|
} finally {
|
|
@@ -1855,11 +2804,11 @@ var addConfigCommand = (program) => {
|
|
|
1855
2804
|
};
|
|
1856
2805
|
|
|
1857
2806
|
// src/cli/version.ts
|
|
1858
|
-
var
|
|
1859
|
-
var
|
|
1860
|
-
var
|
|
2807
|
+
var import_module2 = require("module");
|
|
2808
|
+
var import_meta3 = {};
|
|
2809
|
+
var getSdkVersion2 = () => {
|
|
1861
2810
|
try {
|
|
1862
|
-
const require2 = (0,
|
|
2811
|
+
const require2 = (0, import_module2.createRequire)(import_meta3.url);
|
|
1863
2812
|
for (const p of ["../package.json", "../../package.json"]) {
|
|
1864
2813
|
try {
|
|
1865
2814
|
const pkg = require2(p);
|
|
@@ -1872,7 +2821,7 @@ var getSdkVersion = () => {
|
|
|
1872
2821
|
return "unknown";
|
|
1873
2822
|
};
|
|
1874
2823
|
var displayVersion = () => {
|
|
1875
|
-
const sdkVersion =
|
|
2824
|
+
const sdkVersion = getSdkVersion2();
|
|
1876
2825
|
process.stdout.write(`OAGI SDK version: ${sdkVersion}
|
|
1877
2826
|
`);
|
|
1878
2827
|
process.stdout.write(`Node version: ${process.version}
|