@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.js 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",
@@ -268,29 +268,33 @@ var processLogMessage = (log, logLevel, ...args) => {
268
268
 
269
269
  // src/session/AirtopSessionClient.ts
270
270
  import { NotFoundError } from "@airtop/core";
271
+ import { secondsToMilliseconds as secondsToMilliseconds4 } from "date-fns";
272
+
273
+ // src/async-utils.ts
274
+ import { secondsToMilliseconds as secondsToMilliseconds2 } from "date-fns";
271
275
 
272
276
  // src/types.ts
273
277
  var AirtopError = class extends Error {
274
278
  issues;
275
- constructor(issues) {
279
+ metadata;
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
- import { secondsToMilliseconds as secondsToMilliseconds3 } from "date-fns";
284
-
285
290
  // src/async-utils.ts
286
- import { secondsToMilliseconds as secondsToMilliseconds2 } from "date-fns";
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 = secondsToMilliseconds2(requestOptions?.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 (thrownError.error?.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
+ import { secondsToMilliseconds as secondsToMilliseconds3 } from "date-fns";
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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(600),
686
+ ...this.resolveRequestOptions(requestOptions)
687
+ }
688
+ )
664
689
  );
665
690
  }
666
691
  /**
@@ -678,17 +703,20 @@ var AirtopWindowClient = class extends AirtopBase {
678
703
  if (config?.configuration.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: secondsToMilliseconds3(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: secondsToMilliseconds3(600),
717
+ ...this.resolveRequestOptions(requestOptions)
718
+ }
719
+ )
692
720
  );
693
721
  }
694
722
  /**
@@ -706,17 +734,20 @@ var AirtopWindowClient = class extends AirtopBase {
706
734
  if (config?.configuration.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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: secondsToMilliseconds3(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: config?.outputSchema ? this.convertToJsonSchema(config.outputSchema) : void 0
855
896
  },
856
897
  {
857
898
  timeout: secondsToMilliseconds3(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: config?.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: secondsToMilliseconds3(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: config?.outputSchema ? this.convertToJsonSchema(config.outputSchema) : void 0
1248
+ },
1249
+ {
1250
+ timeout: secondsToMilliseconds4(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