@oagi/oagi 0.1.4 → 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/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 templatePath = import_node_path.default.join(moduleDir, "report_template.html");
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 = [];
@@ -776,10 +826,12 @@ var _Client = class _Client {
776
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}`
777
827
  );
778
828
  }
829
+ const sdkHeaders = getSdkHeaders();
779
830
  this.client = new import_openai.default({
780
831
  baseURL: new URL("./v1", baseURL).href,
781
832
  apiKey,
782
- maxRetries
833
+ maxRetries,
834
+ defaultHeaders: sdkHeaders
783
835
  });
784
836
  logger2.info(`Client initialized with base_url: ${baseURL}`);
785
837
  }
@@ -795,7 +847,7 @@ var _Client = class _Client {
795
847
  return fetch(input, init);
796
848
  }
797
849
  buildHeaders(apiVersion) {
798
- const headers = {};
850
+ const headers = getSdkHeaders();
799
851
  if (apiVersion) {
800
852
  headers["x-api-version"] = apiVersion;
801
853
  }
@@ -1242,6 +1294,784 @@ var DefaultAgent = class {
1242
1294
  }
1243
1295
  };
1244
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
+
1245
2075
  // src/agent/registry.ts
1246
2076
  var agentRegistry = {};
1247
2077
  var asyncAgentRegister = (mode) => {
@@ -1319,11 +2149,119 @@ asyncAgentRegister("thinker")((options = {}) => {
1319
2149
  stepDelay
1320
2150
  );
1321
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
+ );
1322
2260
 
1323
2261
  // src/handler.ts
1324
2262
  var import_robotjs = __toESM(require("robotjs"), 1);
1325
2263
  var import_sharp = __toESM(require("sharp"), 1);
1326
- var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
2264
+ var sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
1327
2265
  var toSharpKernel = (resample) => {
1328
2266
  switch (resample) {
1329
2267
  case "NEAREST":
@@ -1484,7 +2422,7 @@ var DefaultActionHandler = class {
1484
2422
  import_robotjs.default.moveMouse(p1.x, p1.y);
1485
2423
  import_robotjs.default.mouseToggle("down", "left");
1486
2424
  import_robotjs.default.dragMouse(p2.x, p2.y);
1487
- await sleep2(this.#cfg.dragDurationMs);
2425
+ await sleep3(this.#cfg.dragDurationMs);
1488
2426
  import_robotjs.default.mouseToggle("up", "left");
1489
2427
  return;
1490
2428
  }
@@ -1504,7 +2442,7 @@ var DefaultActionHandler = class {
1504
2442
  if (!last) return;
1505
2443
  const modifiers = keys.slice(0, -1);
1506
2444
  import_robotjs.default.keyTap(last, modifiers.length ? modifiers : []);
1507
- await sleep2(this.#cfg.hotkeyDelayMs);
2445
+ await sleep3(this.#cfg.hotkeyDelayMs);
1508
2446
  return;
1509
2447
  }
1510
2448
  case "type": {
@@ -1524,7 +2462,7 @@ var DefaultActionHandler = class {
1524
2462
  return;
1525
2463
  }
1526
2464
  case "wait": {
1527
- await sleep2(this.#cfg.waitDurationMs);
2465
+ await sleep3(this.#cfg.waitDurationMs);
1528
2466
  return;
1529
2467
  }
1530
2468
  case "finish": {
@@ -1614,7 +2552,7 @@ var StepTracker = class extends StepObserver {
1614
2552
 
1615
2553
  // src/cli/agent.ts
1616
2554
  var import_node_mac_permissions = __toESM(require("@hurdlegroup/node-mac-permissions"), 1);
1617
- var logger5 = logger_default("cli.agent");
2555
+ var logger6 = logger_default("cli.agent");
1618
2556
  var checkPermissions = async () => {
1619
2557
  if (process.platform !== "darwin") {
1620
2558
  process.stdout.write(
@@ -1728,7 +2666,7 @@ If you're using pnpm and robotjs is installed, you may need to run: pnpm approve
1728
2666
  if (interrupted) {
1729
2667
  process.exitCode = 130;
1730
2668
  } else {
1731
- logger5.error(`Error during agent execution: ${String(err)}`);
2669
+ logger6.error(`Error during agent execution: ${String(err)}`);
1732
2670
  process.exitCode = 1;
1733
2671
  }
1734
2672
  } finally {
@@ -1866,11 +2804,11 @@ var addConfigCommand = (program) => {
1866
2804
  };
1867
2805
 
1868
2806
  // src/cli/version.ts
1869
- var import_module = require("module");
1870
- var import_meta2 = {};
1871
- var getSdkVersion = () => {
2807
+ var import_module2 = require("module");
2808
+ var import_meta3 = {};
2809
+ var getSdkVersion2 = () => {
1872
2810
  try {
1873
- const require2 = (0, import_module.createRequire)(import_meta2.url);
2811
+ const require2 = (0, import_module2.createRequire)(import_meta3.url);
1874
2812
  for (const p of ["../package.json", "../../package.json"]) {
1875
2813
  try {
1876
2814
  const pkg = require2(p);
@@ -1883,7 +2821,7 @@ var getSdkVersion = () => {
1883
2821
  return "unknown";
1884
2822
  };
1885
2823
  var displayVersion = () => {
1886
- const sdkVersion = getSdkVersion();
2824
+ const sdkVersion = getSdkVersion2();
1887
2825
  process.stdout.write(`OAGI SDK version: ${sdkVersion}
1888
2826
  `);
1889
2827
  process.stdout.write(`Node version: ${process.version}