@airtop/sdk 1.0.0-alpha2.16 → 1.0.0-alpha2.18

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/index.cjs CHANGED
@@ -9,7 +9,7 @@ var require_package = __commonJS({
9
9
  module.exports = {
10
10
  name: "@airtop/sdk",
11
11
  description: "Airtop SDK for TypeScript",
12
- version: "1.0.0-alpha2.16",
12
+ version: "1.0.0-alpha2.18",
13
13
  type: "module",
14
14
  main: "./dist/index.cjs",
15
15
  module: "./dist/index.js",
@@ -47,7 +47,7 @@ var require_package = __commonJS({
47
47
  },
48
48
  dependencies: {
49
49
  "@airtop/json-schema-adapter": "workspace:*",
50
- "@airtop/core": "0.1.0-alpha.29",
50
+ "@airtop/core": "0.1.0-alpha.33",
51
51
  "date-fns": "4.1.0",
52
52
  loglayer: "6.3.3",
53
53
  "serialize-error": "12.0.0",
@@ -269,28 +269,32 @@ var processLogMessage = (log, logLevel, ...args) => {
269
269
  // src/session/AirtopSessionClient.ts
270
270
 
271
271
 
272
+
273
+ // src/async-utils.ts
274
+
275
+
272
276
  // src/types.ts
273
277
  var AirtopError = class extends Error {
274
278
 
275
- constructor(issues) {
279
+
280
+ constructor(issues, metadata) {
276
281
  const errorMessage = issues.map((issue) => issue.message).join("\n");
277
- super(errorMessage);
282
+ const errorMessageWithMetadata = metadata ? `${errorMessage}
283
+ ${JSON.stringify(metadata)}` : errorMessage;
284
+ super(errorMessageWithMetadata);
278
285
  this.issues = issues;
286
+ this.metadata = metadata;
279
287
  }
280
288
  };
281
289
 
282
- // src/window/AirtopWindowClient.ts
283
-
284
-
285
290
  // src/async-utils.ts
286
-
287
291
  var DEFAULT_TIMEOUT_SECONDS = 300;
288
292
  var DEFAULT_POLLING_INTERVAL_MS = 500;
289
293
  async function waitForRequestCompletion(client, requestId, requestOptions) {
290
294
  const startTime = Date.now();
291
295
  const timeoutMs = _datefns.secondsToMilliseconds.call(void 0, _optionalChain([requestOptions, 'optionalAccess', _5 => _5.timeoutInSeconds]) || DEFAULT_TIMEOUT_SECONDS);
292
296
  while (Date.now() - startTime < timeoutMs) {
293
- const apiResponse = await client.requests.getRequestStatus(requestId, requestOptions);
297
+ const apiResponse = await client.requests.getRequestStatusV2(requestId, requestOptions);
294
298
  if (apiResponse.status === "completed") {
295
299
  return apiResponse.response;
296
300
  }
@@ -302,10 +306,22 @@ async function waitForRequestCompletion(client, requestId, requestOptions) {
302
306
  throw new Error("Waiting for request timed out");
303
307
  }
304
308
  async function withRequestCompletionPolling(client, fn, requestOptions) {
305
- const response = await fn();
306
- return waitForRequestCompletion(client, response.requestId, requestOptions);
309
+ try {
310
+ const response = await fn();
311
+ return waitForRequestCompletion(client, response.requestId, requestOptions);
312
+ } catch (thrownError) {
313
+ if (_optionalChain([thrownError, 'access', _6 => _6.error, 'optionalAccess', _7 => _7.errors])) {
314
+ throw new AirtopError(thrownError.error.errors, {
315
+ requestId: thrownError.error.requestId
316
+ });
317
+ }
318
+ throw thrownError;
319
+ }
307
320
  }
308
321
 
322
+ // src/window/AirtopWindowClient.ts
323
+
324
+
309
325
  // src/window/AirtopNode.ts
310
326
  var AirtopNode = class {
311
327
  /**
@@ -363,7 +379,7 @@ var AirtopNode = class {
363
379
  * @param requestOptions - The request options to use for the LLM call
364
380
  */
365
381
  async llm(prompt, config, requestOptions = {}) {
366
- return this.windowClient.llm(prompt, config, requestOptions);
382
+ return this.windowClient.llm(prompt, { ...config, nodeHandleId: this.nodeHandleId }, requestOptions);
367
383
  }
368
384
  /**
369
385
  * Find one element in the node
@@ -572,17 +588,20 @@ var AirtopWindowClient = class extends AirtopBase {
572
588
  this.log.withMetadata({
573
589
  elementDescription
574
590
  }).info("Clicking on element");
575
- return this.client.windows.click(
576
- this.getWindowId(),
577
- {
578
- ...config,
579
- elementDescription,
580
- sessionId: this.sessionId
581
- },
582
- {
583
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
584
- ...this.resolveRequestOptions(requestOptions)
585
- }
591
+ return withRequestCompletionPolling(
592
+ this.client,
593
+ () => this.client.windows.clickAsync(
594
+ this.getWindowId(),
595
+ {
596
+ ...config,
597
+ elementDescription,
598
+ sessionId: this.sessionId
599
+ },
600
+ {
601
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
602
+ ...this.resolveRequestOptions(requestOptions)
603
+ }
604
+ )
586
605
  );
587
606
  }
588
607
  /**
@@ -604,17 +623,20 @@ var AirtopWindowClient = class extends AirtopBase {
604
623
  */
605
624
  async hover(elementDescription, config, requestOptions = {}) {
606
625
  this.log.withMetadata(config).info("Hovering over window");
607
- return this.client.windows.hover(
608
- this.getWindowId(),
609
- {
610
- elementDescription,
611
- sessionId: this.sessionId,
612
- ...config || {}
613
- },
614
- {
615
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
616
- ...this.resolveRequestOptions(requestOptions)
617
- }
626
+ return withRequestCompletionPolling(
627
+ this.client,
628
+ () => this.client.windows.hoverAsync(
629
+ this.getWindowId(),
630
+ {
631
+ elementDescription,
632
+ sessionId: this.sessionId,
633
+ ...config || {}
634
+ },
635
+ {
636
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
637
+ ...this.resolveRequestOptions(requestOptions)
638
+ }
639
+ )
618
640
  );
619
641
  }
620
642
  /**
@@ -650,17 +672,20 @@ var AirtopWindowClient = class extends AirtopBase {
650
672
  */
651
673
  async monitor(condition, config, requestOptions = {}) {
652
674
  this.log.withMetadata().info("Monitoring window");
653
- return this.client.windows.monitor(
654
- this.getWindowId(),
655
- {
656
- condition,
657
- sessionId: this.sessionId,
658
- ...config || {}
659
- },
660
- {
661
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
662
- ...this.resolveRequestOptions(requestOptions)
663
- }
675
+ return withRequestCompletionPolling(
676
+ this.client,
677
+ () => this.client.windows.monitorAsync(
678
+ this.getWindowId(),
679
+ {
680
+ condition,
681
+ sessionId: this.sessionId,
682
+ ...config || {}
683
+ },
684
+ {
685
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
686
+ ...this.resolveRequestOptions(requestOptions)
687
+ }
688
+ )
664
689
  );
665
690
  }
666
691
  /**
@@ -675,20 +700,23 @@ var AirtopWindowClient = class extends AirtopBase {
675
700
  prompt
676
701
  }).info("Performing a page query");
677
702
  const newConfig = config;
678
- if (_optionalChain([config, 'optionalAccess', _6 => _6.configuration, 'access', _7 => _7.outputSchema])) {
703
+ if (_optionalChain([config, 'optionalAccess', _8 => _8.configuration, 'access', _9 => _9.outputSchema])) {
679
704
  newConfig.configuration.outputSchema = this.convertToJsonSchema(config.configuration.outputSchema);
680
705
  }
681
- return this.client.windows.pageQuery(
682
- this.getWindowId(),
683
- {
684
- sessionId: this.sessionId,
685
- prompt,
686
- ...newConfig || {}
687
- },
688
- {
689
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
690
- ...this.resolveRequestOptions(requestOptions)
691
- }
706
+ return withRequestCompletionPolling(
707
+ this.client,
708
+ () => this.client.windows.pageQueryAsync(
709
+ this.getWindowId(),
710
+ {
711
+ sessionId: this.sessionId,
712
+ prompt,
713
+ ...newConfig || {}
714
+ },
715
+ {
716
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
717
+ ...this.resolveRequestOptions(requestOptions)
718
+ }
719
+ )
692
720
  );
693
721
  }
694
722
  /**
@@ -703,20 +731,23 @@ var AirtopWindowClient = class extends AirtopBase {
703
731
  prompt
704
732
  }).info("Performing a paginated extraction");
705
733
  const newConfig = config;
706
- if (_optionalChain([config, 'optionalAccess', _8 => _8.configuration, 'access', _9 => _9.outputSchema])) {
734
+ if (_optionalChain([config, 'optionalAccess', _10 => _10.configuration, 'access', _11 => _11.outputSchema])) {
707
735
  newConfig.configuration.outputSchema = this.convertToJsonSchema(config.configuration.outputSchema);
708
736
  }
709
- return this.client.windows.paginatedExtraction(
710
- this.getWindowId(),
711
- {
712
- prompt,
713
- sessionId: this.sessionId,
714
- ...newConfig || {}
715
- },
716
- {
717
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
718
- ...this.resolveRequestOptions(requestOptions)
719
- }
737
+ return withRequestCompletionPolling(
738
+ this.client,
739
+ () => this.client.windows.paginatedExtractionAsync(
740
+ this.getWindowId(),
741
+ {
742
+ prompt,
743
+ sessionId: this.sessionId,
744
+ ...newConfig || {}
745
+ },
746
+ {
747
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
748
+ ...this.resolveRequestOptions(requestOptions)
749
+ }
750
+ )
720
751
  );
721
752
  }
722
753
  /**
@@ -747,16 +778,19 @@ var AirtopWindowClient = class extends AirtopBase {
747
778
  */
748
779
  async screenshot(config, requestOptions = {}) {
749
780
  this.log.info("Screenshotting window");
750
- const resp = await this.client.windows.screenshot(
751
- this.getWindowId(),
752
- {
753
- sessionId: this.sessionId,
754
- ...config || {}
755
- },
756
- {
757
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
758
- ...this.resolveRequestOptions(requestOptions)
759
- }
781
+ const resp = await withRequestCompletionPolling(
782
+ this.client,
783
+ () => this.client.windows.screenshotAsync(
784
+ this.getWindowId(),
785
+ {
786
+ sessionId: this.sessionId,
787
+ ...config || {}
788
+ },
789
+ {
790
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
791
+ ...this.resolveRequestOptions(requestOptions)
792
+ }
793
+ )
760
794
  );
761
795
  return new AirtopWindowScreenshot(resp);
762
796
  }
@@ -791,17 +825,20 @@ var AirtopWindowClient = class extends AirtopBase {
791
825
  this.log.withMetadata({
792
826
  text
793
827
  }).info("Typing text");
794
- return this.client.windows.type(
795
- this.getWindowId(),
796
- {
797
- sessionId: this.sessionId,
798
- text,
799
- ...config || {}
800
- },
801
- {
802
- timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
803
- ...this.resolveRequestOptions(requestOptions)
804
- }
828
+ return withRequestCompletionPolling(
829
+ this.client,
830
+ () => this.client.windows.typeAsync(
831
+ this.getWindowId(),
832
+ {
833
+ sessionId: this.sessionId,
834
+ text,
835
+ ...config || {}
836
+ },
837
+ {
838
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
839
+ ...this.resolveRequestOptions(requestOptions)
840
+ }
841
+ )
805
842
  );
806
843
  }
807
844
  async extract(prompt, config, requestOptions = {}) {
@@ -851,7 +888,11 @@ var AirtopWindowClient = class extends AirtopBase {
851
888
  {
852
889
  prompt,
853
890
  sessionId: this.sessionId,
854
- ...config || {}
891
+ jobId: this.jobId,
892
+ ...config || {},
893
+ includeWebContext: true,
894
+ // Always include web context for window.llm() calls
895
+ outputSchema: _optionalChain([config, 'optionalAccess', _12 => _12.outputSchema]) ? this.convertToJsonSchema(config.outputSchema) : void 0
855
896
  },
856
897
  {
857
898
  timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
@@ -882,16 +923,12 @@ var AirtopWindowClient = class extends AirtopBase {
882
923
  throw new AirtopError(apiResponse.errors);
883
924
  }
884
925
  try {
885
- if (!apiResponse.data.modelResponse) {
926
+ if (!apiResponse.data.nodeHandle) {
886
927
  return null;
887
928
  }
888
- const nodeData = JSON.parse(apiResponse.data.modelResponse);
889
- if (Object.keys(nodeData).length === 0) {
890
- return null;
891
- }
892
- return new AirtopNode(this, nodeData);
929
+ return new AirtopNode(this, apiResponse.data.nodeHandle);
893
930
  } catch (error) {
894
- this.log.withMetadata({ nodeDataStr: apiResponse.data.modelResponse }).withError(error).error("Error parsing node data");
931
+ this.log.withMetadata({ nodeDataStr: apiResponse.data.nodeHandle }).withError(error).error("Error parsing node data");
895
932
  throw error;
896
933
  }
897
934
  }
@@ -924,21 +961,8 @@ var AirtopWindowClient = class extends AirtopBase {
924
961
  if (apiResponse.errors.length > 0) {
925
962
  throw new AirtopError(apiResponse.errors);
926
963
  }
927
- const nodeHandles = apiResponse.data.modelResponse.split("___DELIM___");
928
- return nodeHandles.map((nodeDataStr) => {
929
- try {
930
- if (!nodeDataStr) {
931
- return null;
932
- }
933
- const nodeData = JSON.parse(nodeDataStr);
934
- if (Object.keys(nodeData).length === 0) {
935
- return null;
936
- }
937
- return new AirtopNode(this, nodeData);
938
- } catch (error) {
939
- this.log.withMetadata({ nodeDataStr }).withError(error).error("Error parsing node data");
940
- }
941
- }).filter((node) => !!node);
964
+ const nodeHandleData = apiResponse.data.nodeHandles;
965
+ return nodeHandleData.map((nodeHandle) => new AirtopNode(this, nodeHandle));
942
966
  }
943
967
  async findMany(prompt, config, requestOptions = {}) {
944
968
  const configOverride = { ...config, optional: false };
@@ -955,6 +979,7 @@ var AirtopWindowClient = class extends AirtopBase {
955
979
  this.getWindowId(),
956
980
  {
957
981
  sessionId: this.sessionId,
982
+ jobId: this.jobId,
958
983
  ...config || {}
959
984
  },
960
985
  {
@@ -972,6 +997,7 @@ var AirtopWindowClient = class extends AirtopBase {
972
997
  {
973
998
  direction,
974
999
  sessionId: this.sessionId,
1000
+ jobId: this.jobId,
975
1001
  ...config || {}
976
1002
  },
977
1003
  {
@@ -981,6 +1007,27 @@ var AirtopWindowClient = class extends AirtopBase {
981
1007
  )
982
1008
  );
983
1009
  }
1010
+ async fillForm(formData, config, requestOptions = {}) {
1011
+ return await withRequestCompletionPolling(
1012
+ this.client,
1013
+ () => this.client.windows.executeAutomation(
1014
+ this.getWindowId(),
1015
+ {
1016
+ sessionId: this.sessionId,
1017
+ ...config || {},
1018
+ automationId: _optionalChain([config, 'optionalAccess', _13 => _13.automationId]) || "auto",
1019
+ parameters: {
1020
+ customData: typeof formData === "string" ? formData : JSON.stringify(formData)
1021
+ // Will be interpreted by the LLM
1022
+ }
1023
+ },
1024
+ {
1025
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
1026
+ ...this.resolveRequestOptions(requestOptions)
1027
+ }
1028
+ )
1029
+ );
1030
+ }
984
1031
  };
985
1032
 
986
1033
  // src/window/AirtopWindow.ts
@@ -1054,6 +1101,9 @@ var AirtopSessionClient = class extends AirtopBase {
1054
1101
  getSessionId() {
1055
1102
  return this.sessionId;
1056
1103
  }
1104
+ async listWindows(requestOptions = {}) {
1105
+ return this.client.sessions.listWindows(this.sessionId, this.resolveRequestOptions(requestOptions));
1106
+ }
1057
1107
  /**
1058
1108
  * Gets the state of the session using the attached session id.
1059
1109
  * @param requestOptions - Request options
@@ -1172,6 +1222,51 @@ var AirtopSessionClient = class extends AirtopBase {
1172
1222
  this.resolveRequestOptions(requestOptions)
1173
1223
  );
1174
1224
  }
1225
+ async llm(prompt, config, requestOptions = {}) {
1226
+ this.log.withMetadata({ prompt }).info("Executing LLM call");
1227
+ const currentWindows = await this.listWindows();
1228
+ if (currentWindows.data.windows.length === 0) {
1229
+ throw new AirtopError([
1230
+ {
1231
+ message: "No windows found in the session. Please create a window before calling the llm() method."
1232
+ }
1233
+ ]);
1234
+ }
1235
+ const firstWindow = currentWindows.data.windows[0];
1236
+ return withRequestCompletionPolling(
1237
+ this.client,
1238
+ () => this.client.windows.llm(
1239
+ firstWindow.windowId,
1240
+ {
1241
+ prompt,
1242
+ sessionId: this.sessionId,
1243
+ jobId: this.jobId,
1244
+ ...config || {},
1245
+ includeWebContext: false,
1246
+ // Do not include web context for session.llm() calls
1247
+ outputSchema: _optionalChain([config, 'optionalAccess', _14 => _14.outputSchema]) ? this.convertToJsonSchema(config.outputSchema) : void 0
1248
+ },
1249
+ {
1250
+ timeout: _datefns.secondsToMilliseconds.call(void 0, 600),
1251
+ ...this.resolveRequestOptions(requestOptions)
1252
+ }
1253
+ )
1254
+ );
1255
+ }
1256
+ /**
1257
+ * Calls the service endpoint.
1258
+ * @param prompt - The prompt to send to the service, describing the actions to take
1259
+ * @param service - The service to call, if not provided, the service will be inferred from the prompt
1260
+ * @param requestOptions - Request options
1261
+ */
1262
+ async service(prompt, service, requestOptions = {}) {
1263
+ this.log.withMetadata({ prompt }).info("Service");
1264
+ return withRequestCompletionPolling(
1265
+ this.client,
1266
+ () => this.client.sessions.service(this.sessionId, { prompt, service }),
1267
+ requestOptions
1268
+ );
1269
+ }
1175
1270
  };
1176
1271
 
1177
1272
  // src/session/AirtopSession.ts
@@ -1230,19 +1325,19 @@ var AirtopClient = class extends AirtopBase {
1230
1325
  */
1231
1326
  constructor(config) {
1232
1327
  super({
1233
- logLevel: _optionalChain([config, 'optionalAccess', _10 => _10.logLevel]),
1328
+ logLevel: _optionalChain([config, 'optionalAccess', _15 => _15.logLevel]),
1234
1329
  client: new (0, _core.Airtop)({
1235
1330
  maxRetries: 0,
1236
1331
  timeout: _minutesToMilliseconds.minutesToMilliseconds.call(void 0, 1),
1237
1332
  apiKey: config.apiKey,
1238
- baseURL: _optionalChain([config, 'optionalAccess', _11 => _11.airtopUrl]),
1239
- logLevel: _optionalChain([config, 'optionalAccess', _12 => _12.logLevel]) || "off",
1333
+ baseURL: _optionalChain([config, 'optionalAccess', _16 => _16.airtopUrl]),
1334
+ logLevel: _optionalChain([config, 'optionalAccess', _17 => _17.logLevel]) || "off",
1240
1335
  defaultHeaders: {
1241
1336
  "x-airtop-sdk-source": "typescript",
1242
1337
  "x-airtop-sdk-version": version
1243
1338
  }
1244
1339
  }),
1245
- log: _optionalChain([config, 'optionalAccess', _13 => _13.logger]) || new (0, _loglayer.LogLayer)({
1340
+ log: _optionalChain([config, 'optionalAccess', _18 => _18.logger]) || new (0, _loglayer.LogLayer)({
1246
1341
  errorSerializer: _serializeerror.serializeError,
1247
1342
  transport: new (0, _loglayer.ConsoleTransport)({
1248
1343
  logger: console,
@@ -1281,8 +1376,8 @@ var AirtopClient = class extends AirtopBase {
1281
1376
  * @returns A new AirtopSession instance
1282
1377
  */
1283
1378
  async createSession(config, options = {}) {
1284
- const skipWaitSessionReady = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _14 => _14.skipWaitSessionReady]), () => ( false));
1285
- _optionalChainDelete([config, 'optionalAccess', _15 => delete _15.skipWaitSessionReady]);
1379
+ const skipWaitSessionReady = _nullishCoalesce(_optionalChain([config, 'optionalAccess', _19 => _19.skipWaitSessionReady]), () => ( false));
1380
+ _optionalChainDelete([config, 'optionalAccess', _20 => delete _20.skipWaitSessionReady]);
1286
1381
  const sessionResponse = await this.client.sessions.create(
1287
1382
  {
1288
1383
  configuration: config
@@ -1489,19 +1584,19 @@ var AirtopAgentClient = class extends AirtopBase {
1489
1584
  */
1490
1585
  constructor(config) {
1491
1586
  super({
1492
- logLevel: _optionalChain([config, 'optionalAccess', _16 => _16.logLevel]),
1587
+ logLevel: _optionalChain([config, 'optionalAccess', _21 => _21.logLevel]),
1493
1588
  client: new (0, _core.Airtop)({
1494
1589
  maxRetries: 0,
1495
1590
  timeout: _datefns.minutesToMilliseconds.call(void 0, 1),
1496
1591
  apiKey: config.apiKey,
1497
- baseURL: _optionalChain([config, 'optionalAccess', _17 => _17.airtopUrl]),
1498
- logLevel: _optionalChain([config, 'optionalAccess', _18 => _18.logLevel]) || "off",
1592
+ baseURL: _optionalChain([config, 'optionalAccess', _22 => _22.airtopUrl]),
1593
+ logLevel: _optionalChain([config, 'optionalAccess', _23 => _23.logLevel]) || "off",
1499
1594
  defaultHeaders: {
1500
1595
  "x-airtop-sdk-source": "typescript",
1501
1596
  "x-airtop-sdk-version": _process.version
1502
1597
  }
1503
1598
  }),
1504
- log: _optionalChain([config, 'optionalAccess', _19 => _19.logger]) || new (0, _loglayer.LogLayer)({
1599
+ log: _optionalChain([config, 'optionalAccess', _24 => _24.logger]) || new (0, _loglayer.LogLayer)({
1505
1600
  errorSerializer: _serializeerror.serializeError,
1506
1601
  transport: new (0, _loglayer.ConsoleTransport)({
1507
1602
  logger: console,