exa-js 1.5.13 → 1.7.0

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.mjs CHANGED
@@ -1,8 +1,650 @@
1
1
  // src/index.ts
2
2
  import fetch, { Headers } from "cross-fetch";
3
+
4
+ // src/errors.ts
5
+ var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => {
6
+ HttpStatusCode2[HttpStatusCode2["BadRequest"] = 400] = "BadRequest";
7
+ HttpStatusCode2[HttpStatusCode2["NotFound"] = 404] = "NotFound";
8
+ HttpStatusCode2[HttpStatusCode2["Unauthorized"] = 401] = "Unauthorized";
9
+ HttpStatusCode2[HttpStatusCode2["Forbidden"] = 403] = "Forbidden";
10
+ HttpStatusCode2[HttpStatusCode2["TooManyRequests"] = 429] = "TooManyRequests";
11
+ HttpStatusCode2[HttpStatusCode2["RequestTimeout"] = 408] = "RequestTimeout";
12
+ HttpStatusCode2[HttpStatusCode2["InternalServerError"] = 500] = "InternalServerError";
13
+ HttpStatusCode2[HttpStatusCode2["ServiceUnavailable"] = 503] = "ServiceUnavailable";
14
+ return HttpStatusCode2;
15
+ })(HttpStatusCode || {});
16
+ var ExaError = class extends Error {
17
+ /**
18
+ * Create a new ExaError
19
+ * @param message Error message
20
+ * @param statusCode HTTP status code
21
+ * @param timestamp ISO timestamp from API
22
+ * @param path Path that caused the error
23
+ */
24
+ constructor(message, statusCode, timestamp, path) {
25
+ super(message);
26
+ this.name = "ExaError";
27
+ this.statusCode = statusCode;
28
+ this.timestamp = timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
29
+ this.path = path;
30
+ }
31
+ };
32
+
33
+ // src/websets/base.ts
34
+ var WebsetsBaseClient = class {
35
+ /**
36
+ * Initialize a new Websets base client
37
+ * @param client The Exa client instance
38
+ */
39
+ constructor(client) {
40
+ this.client = client;
41
+ }
42
+ /**
43
+ * Make a request to the Websets API
44
+ * @param endpoint The endpoint path
45
+ * @param method The HTTP method
46
+ * @param data Optional request body data
47
+ * @param params Optional query parameters
48
+ * @returns The response JSON
49
+ * @throws ExaError with API error details if the request fails
50
+ */
51
+ async request(endpoint, method = "POST", data, params) {
52
+ return this.client.request(`/websets${endpoint}`, method, data, params);
53
+ }
54
+ /**
55
+ * Helper to build pagination parameters
56
+ * @param pagination The pagination parameters
57
+ * @returns QueryParams object with pagination parameters
58
+ */
59
+ buildPaginationParams(pagination) {
60
+ const params = {};
61
+ if (!pagination) return params;
62
+ if (pagination.cursor) params.cursor = pagination.cursor;
63
+ if (pagination.limit) params.limit = pagination.limit;
64
+ return params;
65
+ }
66
+ };
67
+
68
+ // src/websets/enrichments.ts
69
+ var WebsetEnrichmentsClient = class extends WebsetsBaseClient {
70
+ /**
71
+ * Create an Enrichment for a Webset
72
+ * @param websetId The ID of the Webset
73
+ * @param params The enrichment parameters
74
+ * @returns The created Webset Enrichment
75
+ */
76
+ async create(websetId, params) {
77
+ return this.request(
78
+ `/v0/websets/${websetId}/enrichments`,
79
+ "POST",
80
+ params
81
+ );
82
+ }
83
+ /**
84
+ * Get an Enrichment by ID
85
+ * @param websetId The ID of the Webset
86
+ * @param id The ID of the Enrichment
87
+ * @returns The Webset Enrichment
88
+ */
89
+ async get(websetId, id) {
90
+ return this.request(
91
+ `/v0/websets/${websetId}/enrichments/${id}`,
92
+ "GET"
93
+ );
94
+ }
95
+ /**
96
+ * Delete an Enrichment
97
+ * @param websetId The ID of the Webset
98
+ * @param id The ID of the Enrichment
99
+ * @returns The deleted Webset Enrichment
100
+ */
101
+ async delete(websetId, id) {
102
+ return this.request(
103
+ `/v0/websets/${websetId}/enrichments/${id}`,
104
+ "DELETE"
105
+ );
106
+ }
107
+ /**
108
+ * Cancel a running Enrichment
109
+ * @param websetId The ID of the Webset
110
+ * @param id The ID of the Enrichment
111
+ * @returns The canceled Webset Enrichment
112
+ */
113
+ async cancel(websetId, id) {
114
+ return this.request(
115
+ `/v0/websets/${websetId}/enrichments/${id}/cancel`,
116
+ "POST"
117
+ );
118
+ }
119
+ };
120
+
121
+ // src/websets/events.ts
122
+ var EventsClient = class extends WebsetsBaseClient {
123
+ /**
124
+ * Initialize a new Events client
125
+ * @param client The Exa client instance
126
+ */
127
+ constructor(client) {
128
+ super(client);
129
+ }
130
+ /**
131
+ * List all Events
132
+ * @param options Optional filtering and pagination options
133
+ * @returns The list of Events
134
+ */
135
+ async list(options) {
136
+ const params = {
137
+ cursor: options?.cursor,
138
+ limit: options?.limit,
139
+ types: options?.types
140
+ };
141
+ return this.request(
142
+ "/v0/events",
143
+ "GET",
144
+ void 0,
145
+ params
146
+ );
147
+ }
148
+ /**
149
+ * Get an Event by ID
150
+ * @param id The ID of the Event
151
+ * @returns The Event
152
+ */
153
+ async get(id) {
154
+ return this.request(`/v0/events/${id}`, "GET");
155
+ }
156
+ };
157
+
158
+ // src/websets/items.ts
159
+ var WebsetItemsClient = class extends WebsetsBaseClient {
160
+ /**
161
+ * List all Items for a Webset
162
+ * @param websetId The ID of the Webset
163
+ * @param params - Optional pagination parameters
164
+ * @returns A promise that resolves with the list of Items
165
+ */
166
+ list(websetId, params) {
167
+ const queryParams = this.buildPaginationParams(params);
168
+ return this.request(
169
+ `/v0/websets/${websetId}/items`,
170
+ "GET",
171
+ void 0,
172
+ queryParams
173
+ );
174
+ }
175
+ /**
176
+ * Iterate through all Items in a Webset, handling pagination automatically
177
+ * @param websetId The ID of the Webset
178
+ * @param options Pagination options
179
+ * @returns Async generator of Webset Items
180
+ */
181
+ async *listAll(websetId, options) {
182
+ let cursor = void 0;
183
+ const pageOptions = options ? { ...options } : {};
184
+ while (true) {
185
+ pageOptions.cursor = cursor;
186
+ const response = await this.list(websetId, pageOptions);
187
+ for (const item of response.data) {
188
+ yield item;
189
+ }
190
+ if (!response.hasMore || !response.nextCursor) {
191
+ break;
192
+ }
193
+ cursor = response.nextCursor;
194
+ }
195
+ }
196
+ /**
197
+ * Collect all items from a Webset into an array
198
+ * @param websetId The ID of the Webset
199
+ * @param options Pagination options
200
+ * @returns Promise resolving to an array of all Webset Items
201
+ */
202
+ async getAll(websetId, options) {
203
+ const items = [];
204
+ for await (const item of this.listAll(websetId, options)) {
205
+ items.push(item);
206
+ }
207
+ return items;
208
+ }
209
+ /**
210
+ * Get an Item by ID
211
+ * @param websetId The ID of the Webset
212
+ * @param id The ID of the Item
213
+ * @returns The Webset Item
214
+ */
215
+ async get(websetId, id) {
216
+ return this.request(
217
+ `/v0/websets/${websetId}/items/${id}`,
218
+ "GET"
219
+ );
220
+ }
221
+ /**
222
+ * Delete an Item
223
+ * @param websetId The ID of the Webset
224
+ * @param id The ID of the Item
225
+ * @returns The deleted Webset Item
226
+ */
227
+ async delete(websetId, id) {
228
+ return this.request(
229
+ `/v0/websets/${websetId}/items/${id}`,
230
+ "DELETE"
231
+ );
232
+ }
233
+ };
234
+
235
+ // src/websets/openapi.ts
236
+ var CreateEnrichmentParametersFormat = /* @__PURE__ */ ((CreateEnrichmentParametersFormat2) => {
237
+ CreateEnrichmentParametersFormat2["text"] = "text";
238
+ CreateEnrichmentParametersFormat2["date"] = "date";
239
+ CreateEnrichmentParametersFormat2["number"] = "number";
240
+ CreateEnrichmentParametersFormat2["options"] = "options";
241
+ CreateEnrichmentParametersFormat2["email"] = "email";
242
+ CreateEnrichmentParametersFormat2["phone"] = "phone";
243
+ return CreateEnrichmentParametersFormat2;
244
+ })(CreateEnrichmentParametersFormat || {});
245
+ var CreateWebsetSearchParametersBehaviour = /* @__PURE__ */ ((CreateWebsetSearchParametersBehaviour2) => {
246
+ CreateWebsetSearchParametersBehaviour2["override"] = "override";
247
+ return CreateWebsetSearchParametersBehaviour2;
248
+ })(CreateWebsetSearchParametersBehaviour || {});
249
+ var EventType = /* @__PURE__ */ ((EventType2) => {
250
+ EventType2["webset_created"] = "webset.created";
251
+ EventType2["webset_deleted"] = "webset.deleted";
252
+ EventType2["webset_paused"] = "webset.paused";
253
+ EventType2["webset_idle"] = "webset.idle";
254
+ EventType2["webset_search_created"] = "webset.search.created";
255
+ EventType2["webset_search_canceled"] = "webset.search.canceled";
256
+ EventType2["webset_search_completed"] = "webset.search.completed";
257
+ EventType2["webset_search_updated"] = "webset.search.updated";
258
+ EventType2["webset_export_created"] = "webset.export.created";
259
+ EventType2["webset_export_completed"] = "webset.export.completed";
260
+ EventType2["webset_item_created"] = "webset.item.created";
261
+ EventType2["webset_item_enriched"] = "webset.item.enriched";
262
+ return EventType2;
263
+ })(EventType || {});
264
+ var WebhookStatus = /* @__PURE__ */ ((WebhookStatus2) => {
265
+ WebhookStatus2["active"] = "active";
266
+ WebhookStatus2["inactive"] = "inactive";
267
+ return WebhookStatus2;
268
+ })(WebhookStatus || {});
269
+ var WebsetStatus = /* @__PURE__ */ ((WebsetStatus2) => {
270
+ WebsetStatus2["idle"] = "idle";
271
+ WebsetStatus2["running"] = "running";
272
+ WebsetStatus2["paused"] = "paused";
273
+ return WebsetStatus2;
274
+ })(WebsetStatus || {});
275
+ var WebsetEnrichmentStatus = /* @__PURE__ */ ((WebsetEnrichmentStatus2) => {
276
+ WebsetEnrichmentStatus2["pending"] = "pending";
277
+ WebsetEnrichmentStatus2["canceled"] = "canceled";
278
+ WebsetEnrichmentStatus2["completed"] = "completed";
279
+ return WebsetEnrichmentStatus2;
280
+ })(WebsetEnrichmentStatus || {});
281
+ var WebsetEnrichmentFormat = /* @__PURE__ */ ((WebsetEnrichmentFormat2) => {
282
+ WebsetEnrichmentFormat2["text"] = "text";
283
+ WebsetEnrichmentFormat2["date"] = "date";
284
+ WebsetEnrichmentFormat2["number"] = "number";
285
+ WebsetEnrichmentFormat2["options"] = "options";
286
+ WebsetEnrichmentFormat2["email"] = "email";
287
+ WebsetEnrichmentFormat2["phone"] = "phone";
288
+ return WebsetEnrichmentFormat2;
289
+ })(WebsetEnrichmentFormat || {});
290
+ var WebsetItemSource = /* @__PURE__ */ ((WebsetItemSource2) => {
291
+ WebsetItemSource2["search"] = "search";
292
+ return WebsetItemSource2;
293
+ })(WebsetItemSource || {});
294
+ var WebsetItemEvaluationSatisfied = /* @__PURE__ */ ((WebsetItemEvaluationSatisfied2) => {
295
+ WebsetItemEvaluationSatisfied2["yes"] = "yes";
296
+ WebsetItemEvaluationSatisfied2["no"] = "no";
297
+ WebsetItemEvaluationSatisfied2["unclear"] = "unclear";
298
+ return WebsetItemEvaluationSatisfied2;
299
+ })(WebsetItemEvaluationSatisfied || {});
300
+ var WebsetSearchCanceledReason = /* @__PURE__ */ ((WebsetSearchCanceledReason2) => {
301
+ WebsetSearchCanceledReason2["webset_deleted"] = "webset_deleted";
302
+ WebsetSearchCanceledReason2["webset_canceled"] = "webset_canceled";
303
+ return WebsetSearchCanceledReason2;
304
+ })(WebsetSearchCanceledReason || {});
305
+ var WebsetSearchStatus = /* @__PURE__ */ ((WebsetSearchStatus2) => {
306
+ WebsetSearchStatus2["created"] = "created";
307
+ WebsetSearchStatus2["running"] = "running";
308
+ WebsetSearchStatus2["completed"] = "completed";
309
+ WebsetSearchStatus2["canceled"] = "canceled";
310
+ return WebsetSearchStatus2;
311
+ })(WebsetSearchStatus || {});
312
+
313
+ // src/websets/searches.ts
314
+ var WebsetSearchesClient = class extends WebsetsBaseClient {
315
+ /**
316
+ * Create a new Search for the Webset
317
+ * @param websetId The ID of the Webset
318
+ * @param params The search parameters
319
+ * @returns The created Webset Search
320
+ */
321
+ async create(websetId, params) {
322
+ return this.request(
323
+ `/v0/websets/${websetId}/searches`,
324
+ "POST",
325
+ params
326
+ );
327
+ }
328
+ /**
329
+ * Get a Search by ID
330
+ * @param websetId The ID of the Webset
331
+ * @param id The ID of the Search
332
+ * @returns The Webset Search
333
+ */
334
+ async get(websetId, id) {
335
+ return this.request(
336
+ `/v0/websets/${websetId}/searches/${id}`,
337
+ "GET"
338
+ );
339
+ }
340
+ /**
341
+ * Cancel a running Search
342
+ * @param websetId The ID of the Webset
343
+ * @param id The ID of the Search
344
+ * @returns The canceled Webset Search
345
+ */
346
+ async cancel(websetId, id) {
347
+ return this.request(
348
+ `/v0/websets/${websetId}/searches/${id}/cancel`,
349
+ "POST"
350
+ );
351
+ }
352
+ };
353
+
354
+ // src/websets/webhooks.ts
355
+ var WebsetWebhooksClient = class extends WebsetsBaseClient {
356
+ /**
357
+ * Create a Webhook
358
+ * @param params The webhook parameters
359
+ * @returns The created Webhook
360
+ */
361
+ async create(params) {
362
+ return this.request("/v0/webhooks", "POST", params);
363
+ }
364
+ /**
365
+ * Get a Webhook by ID
366
+ * @param id The ID of the Webhook
367
+ * @returns The Webhook
368
+ */
369
+ async get(id) {
370
+ return this.request(`/v0/webhooks/${id}`, "GET");
371
+ }
372
+ /**
373
+ * List all Webhooks
374
+ * @param options Pagination options
375
+ * @returns The list of Webhooks
376
+ */
377
+ async list(options) {
378
+ const params = this.buildPaginationParams(options);
379
+ return this.request(
380
+ "/v0/webhooks",
381
+ "GET",
382
+ void 0,
383
+ params
384
+ );
385
+ }
386
+ /**
387
+ * Iterate through all Webhooks, handling pagination automatically
388
+ * @param options Pagination options
389
+ * @returns Async generator of Webhooks
390
+ */
391
+ async *listAll(options) {
392
+ let cursor = void 0;
393
+ const pageOptions = options ? { ...options } : {};
394
+ while (true) {
395
+ pageOptions.cursor = cursor;
396
+ const response = await this.list(pageOptions);
397
+ for (const webhook of response.data) {
398
+ yield webhook;
399
+ }
400
+ if (!response.hasMore || !response.nextCursor) {
401
+ break;
402
+ }
403
+ cursor = response.nextCursor;
404
+ }
405
+ }
406
+ /**
407
+ * Collect all Webhooks into an array
408
+ * @param options Pagination options
409
+ * @returns Promise resolving to an array of all Webhooks
410
+ */
411
+ async getAll(options) {
412
+ const webhooks = [];
413
+ for await (const webhook of this.listAll(options)) {
414
+ webhooks.push(webhook);
415
+ }
416
+ return webhooks;
417
+ }
418
+ /**
419
+ * Update a Webhook
420
+ * @param id The ID of the Webhook
421
+ * @param params The webhook update parameters (events, metadata, url)
422
+ * @returns The updated Webhook
423
+ */
424
+ async update(id, params) {
425
+ return this.request(`/v0/webhooks/${id}`, "PATCH", params);
426
+ }
427
+ /**
428
+ * Delete a Webhook
429
+ * @param id The ID of the Webhook
430
+ * @returns The deleted Webhook
431
+ */
432
+ async delete(id) {
433
+ return this.request(`/v0/webhooks/${id}`, "DELETE");
434
+ }
435
+ /**
436
+ * List all attempts for a Webhook
437
+ * @param id The ID of the Webhook
438
+ * @param options Pagination and filtering options
439
+ * @returns The list of Webhook attempts
440
+ */
441
+ async listAttempts(id, options) {
442
+ const params = {
443
+ cursor: options?.cursor,
444
+ limit: options?.limit,
445
+ eventType: options?.eventType
446
+ };
447
+ return this.request(
448
+ `/v0/webhooks/${id}/attempts`,
449
+ "GET",
450
+ void 0,
451
+ params
452
+ );
453
+ }
454
+ /**
455
+ * Iterate through all attempts for a Webhook, handling pagination automatically
456
+ * @param id The ID of the Webhook
457
+ * @param options Pagination and filtering options
458
+ * @returns Async generator of Webhook attempts
459
+ */
460
+ async *listAllAttempts(id, options) {
461
+ let cursor = void 0;
462
+ const pageOptions = options ? { ...options } : {};
463
+ while (true) {
464
+ pageOptions.cursor = cursor;
465
+ const response = await this.listAttempts(id, pageOptions);
466
+ for (const attempt of response.data) {
467
+ yield attempt;
468
+ }
469
+ if (!response.hasMore || !response.nextCursor) {
470
+ break;
471
+ }
472
+ cursor = response.nextCursor;
473
+ }
474
+ }
475
+ /**
476
+ * Collect all attempts for a Webhook into an array
477
+ * @param id The ID of the Webhook
478
+ * @param options Pagination and filtering options
479
+ * @returns Promise resolving to an array of all Webhook attempts
480
+ */
481
+ async getAllAttempts(id, options) {
482
+ const attempts = [];
483
+ for await (const attempt of this.listAllAttempts(id, options)) {
484
+ attempts.push(attempt);
485
+ }
486
+ return attempts;
487
+ }
488
+ };
489
+
490
+ // src/websets/client.ts
491
+ var WebsetsClient = class extends WebsetsBaseClient {
492
+ /**
493
+ * Initialize a new Websets client
494
+ * @param client The Exa client instance
495
+ */
496
+ constructor(client) {
497
+ super(client);
498
+ this.events = new EventsClient(client);
499
+ this.items = new WebsetItemsClient(client);
500
+ this.searches = new WebsetSearchesClient(client);
501
+ this.enrichments = new WebsetEnrichmentsClient(client);
502
+ this.webhooks = new WebsetWebhooksClient(client);
503
+ }
504
+ /**
505
+ * Create a new Webset
506
+ * @param params The Webset creation parameters
507
+ * @returns The created Webset
508
+ */
509
+ async create(params) {
510
+ return this.request("/v0/websets", "POST", params);
511
+ }
512
+ /**
513
+ * Get a Webset by ID
514
+ * @param id The ID of the Webset
515
+ * @param expand Optional array of relations to expand
516
+ * @returns The Webset
517
+ */
518
+ async get(id, expand) {
519
+ const params = {};
520
+ if (expand) {
521
+ params.expand = expand;
522
+ }
523
+ return this.request(
524
+ `/v0/websets/${id}`,
525
+ "GET",
526
+ void 0,
527
+ params
528
+ );
529
+ }
530
+ /**
531
+ * List all Websets
532
+ * @param options Pagination options (filtering by status is not supported by API)
533
+ * @returns The list of Websets
534
+ */
535
+ async list(options) {
536
+ const params = this.buildPaginationParams(options);
537
+ return this.request(
538
+ "/v0/websets",
539
+ "GET",
540
+ void 0,
541
+ params
542
+ );
543
+ }
544
+ /**
545
+ * Iterate through all Websets, handling pagination automatically
546
+ * @param options Pagination options
547
+ * @returns Async generator of Websets
548
+ */
549
+ async *listAll(options) {
550
+ let cursor = void 0;
551
+ const pageOptions = options ? { ...options } : {};
552
+ while (true) {
553
+ pageOptions.cursor = cursor;
554
+ const response = await this.list(pageOptions);
555
+ for (const webset of response.data) {
556
+ yield webset;
557
+ }
558
+ if (!response.hasMore || !response.nextCursor) {
559
+ break;
560
+ }
561
+ cursor = response.nextCursor;
562
+ }
563
+ }
564
+ /**
565
+ * Collect all Websets into an array
566
+ * @param options Pagination options
567
+ * @returns Promise resolving to an array of all Websets
568
+ */
569
+ async getAll(options) {
570
+ const websets = [];
571
+ for await (const webset of this.listAll(options)) {
572
+ websets.push(webset);
573
+ }
574
+ return websets;
575
+ }
576
+ /**
577
+ * Update a Webset
578
+ * @param id The ID of the Webset
579
+ * @param params The Webset update parameters
580
+ * @returns The updated Webset
581
+ */
582
+ async update(id, params) {
583
+ return this.request(`/v0/websets/${id}`, "POST", params);
584
+ }
585
+ /**
586
+ * Delete a Webset
587
+ * @param id The ID of the Webset
588
+ * @returns The deleted Webset
589
+ */
590
+ async delete(id) {
591
+ return this.request(`/v0/websets/${id}`, "DELETE");
592
+ }
593
+ /**
594
+ * Cancel a running Webset
595
+ * @param id The ID or external ID of the Webset
596
+ * @returns The canceled Webset (as returned by the API)
597
+ */
598
+ async cancel(id) {
599
+ return this.request(`/v0/websets/${id}/cancel`, "POST");
600
+ }
601
+ /**
602
+ * Wait until a Webset is idle
603
+ * @param id The ID of the Webset
604
+ * @param options Configuration options for timeout and polling
605
+ * @returns The Webset once it becomes idle
606
+ * @throws Error if the Webset does not become idle within the timeout
607
+ */
608
+ async waitUntilIdle(id, options) {
609
+ let timeout;
610
+ let pollInterval = 1e3;
611
+ let onPoll;
612
+ if (typeof options === "number") {
613
+ timeout = options;
614
+ } else if (options) {
615
+ timeout = options.timeout;
616
+ pollInterval = options.pollInterval || 1e3;
617
+ onPoll = options.onPoll;
618
+ }
619
+ const startTime = Date.now();
620
+ while (true) {
621
+ const webset = await this.get(id);
622
+ if (onPoll) {
623
+ onPoll(webset.status);
624
+ }
625
+ if (webset.status === "idle" /* idle */) {
626
+ return webset;
627
+ }
628
+ if (timeout && Date.now() - startTime > timeout) {
629
+ throw new ExaError(
630
+ `Webset ${id} did not reach idle state within ${timeout}ms. Current status: ${webset.status}`,
631
+ 408 /* RequestTimeout */
632
+ );
633
+ }
634
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
635
+ }
636
+ }
637
+ };
638
+
639
+ // src/index.ts
3
640
  var fetchImpl = typeof global !== "undefined" && global.fetch ? global.fetch : fetch;
4
641
  var HeadersImpl = typeof global !== "undefined" && global.Headers ? global.Headers : Headers;
5
- var Exa = class {
642
+ var ResearchStatus = /* @__PURE__ */ ((ResearchStatus2) => {
643
+ ResearchStatus2["completed"] = "completed";
644
+ ResearchStatus2["failed"] = "failed";
645
+ return ResearchStatus2;
646
+ })(ResearchStatus || {});
647
+ var Exa2 = class {
6
648
  /**
7
649
  * Helper method to separate out the contents-specific options from the rest.
8
650
  */
@@ -22,20 +664,14 @@ var Exa = class {
22
664
  if (text === void 0 && summary === void 0 && highlights === void 0 && extras === void 0) {
23
665
  contentsOptions.text = true;
24
666
  }
25
- if (text !== void 0)
26
- contentsOptions.text = text;
27
- if (summary !== void 0)
28
- contentsOptions.summary = summary;
29
- if (highlights !== void 0)
30
- contentsOptions.highlights = highlights;
31
- if (subpages !== void 0)
32
- contentsOptions.subpages = subpages;
667
+ if (text !== void 0) contentsOptions.text = text;
668
+ if (summary !== void 0) contentsOptions.summary = summary;
669
+ if (highlights !== void 0) contentsOptions.highlights = highlights;
670
+ if (subpages !== void 0) contentsOptions.subpages = subpages;
33
671
  if (subpageTarget !== void 0)
34
672
  contentsOptions.subpageTarget = subpageTarget;
35
- if (extras !== void 0)
36
- contentsOptions.extras = extras;
37
- if (livecrawl !== void 0)
38
- contentsOptions.livecrawl = livecrawl;
673
+ if (extras !== void 0) contentsOptions.extras = extras;
674
+ if (livecrawl !== void 0) contentsOptions.livecrawl = livecrawl;
39
675
  if (livecrawlTimeout !== void 0)
40
676
  contentsOptions.livecrawlTimeout = livecrawlTimeout;
41
677
  return {
@@ -53,8 +689,9 @@ var Exa = class {
53
689
  if (!apiKey) {
54
690
  apiKey = process.env.EXASEARCH_API_KEY;
55
691
  if (!apiKey) {
56
- throw new Error(
57
- "API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)"
692
+ throw new ExaError(
693
+ "API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)",
694
+ 401 /* Unauthorized */
58
695
  );
59
696
  }
60
697
  }
@@ -63,31 +700,61 @@ var Exa = class {
63
700
  "Content-Type": "application/json",
64
701
  "User-Agent": "exa-node 1.4.0"
65
702
  });
703
+ this.websets = new WebsetsClient(this);
66
704
  }
67
705
  /**
68
706
  * Makes a request to the Exa API.
69
707
  * @param {string} endpoint - The API endpoint to call.
70
708
  * @param {string} method - The HTTP method to use.
71
709
  * @param {any} [body] - The request body for POST requests.
710
+ * @param {Record<string, any>} [params] - The query parameters.
72
711
  * @returns {Promise<any>} The response from the API.
712
+ * @throws {ExaError} When any API request fails with structured error information
73
713
  */
74
- async request(endpoint, method, body) {
75
- const response = await fetchImpl(this.baseURL + endpoint, {
714
+ async request(endpoint, method, body, params) {
715
+ let url = this.baseURL + endpoint;
716
+ if (params && Object.keys(params).length > 0) {
717
+ const searchParams = new URLSearchParams();
718
+ for (const [key, value] of Object.entries(params)) {
719
+ if (Array.isArray(value)) {
720
+ for (const item of value) {
721
+ searchParams.append(key, item);
722
+ }
723
+ } else if (value !== void 0) {
724
+ searchParams.append(key, String(value));
725
+ }
726
+ }
727
+ url += `?${searchParams.toString()}`;
728
+ }
729
+ const response = await fetchImpl(url, {
76
730
  method,
77
731
  headers: this.headers,
78
732
  body: body ? JSON.stringify(body) : void 0
79
733
  });
80
734
  if (!response.ok) {
81
- const message = (await response.json()).error;
82
- throw new Error(
83
- `Request failed with status ${response.status}. ${message}`
735
+ const errorData = await response.json();
736
+ if (!errorData.statusCode) {
737
+ errorData.statusCode = response.status;
738
+ }
739
+ if (!errorData.timestamp) {
740
+ errorData.timestamp = (/* @__PURE__ */ new Date()).toISOString();
741
+ }
742
+ if (!errorData.path) {
743
+ errorData.path = endpoint;
744
+ }
745
+ const message = errorData.error || "Unknown error";
746
+ throw new ExaError(
747
+ message,
748
+ response.status,
749
+ errorData.timestamp,
750
+ errorData.path
84
751
  );
85
752
  }
86
753
  return await response.json();
87
754
  }
88
755
  /**
89
756
  * Performs a search with an Exa prompt-engineered query.
90
- *
757
+ *
91
758
  * @param {string} query - The query string.
92
759
  * @param {RegularSearchOptions} [options] - Additional search options
93
760
  * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.
@@ -97,7 +764,7 @@ var Exa = class {
97
764
  }
98
765
  /**
99
766
  * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.
100
- *
767
+ *
101
768
  * @param {string} query - The query string.
102
769
  * @param {RegularSearchOptions & T} [options] - Additional search + contents options
103
770
  * @returns {Promise<SearchResponse<T>>} A list of relevant search results with requested contents.
@@ -141,7 +808,10 @@ var Exa = class {
141
808
  */
142
809
  async getContents(urls, options) {
143
810
  if (!urls || Array.isArray(urls) && urls.length === 0) {
144
- throw new Error("Must provide at least one URL");
811
+ throw new ExaError(
812
+ "Must provide at least one URL",
813
+ 400 /* BadRequest */
814
+ );
145
815
  }
146
816
  let requestUrls;
147
817
  if (typeof urls === "string") {
@@ -162,7 +832,7 @@ var Exa = class {
162
832
  * @param {string} query - The question or query to answer.
163
833
  * @param {AnswerOptions} [options] - Additional options for answer generation.
164
834
  * @returns {Promise<AnswerResponse>} The generated answer and source references.
165
- *
835
+ *
166
836
  * Example with systemPrompt:
167
837
  * ```ts
168
838
  * const answer = await exa.answer("What is quantum computing?", {
@@ -171,7 +841,7 @@ var Exa = class {
171
841
  * systemPrompt: "Answer in a technical manner suitable for experts."
172
842
  * });
173
843
  * ```
174
- *
844
+ *
175
845
  * Note: For streaming responses, use the `streamAnswer` method:
176
846
  * ```ts
177
847
  * for await (const chunk of exa.streamAnswer(query)) {
@@ -181,8 +851,9 @@ var Exa = class {
181
851
  */
182
852
  async answer(query, options) {
183
853
  if (options?.stream) {
184
- throw new Error(
185
- "For streaming responses, please use streamAnswer() instead:\n\nfor await (const chunk of exa.streamAnswer(query)) {\n // Handle chunks\n}"
854
+ throw new ExaError(
855
+ "For streaming responses, please use streamAnswer() instead:\n\nfor await (const chunk of exa.streamAnswer(query)) {\n // Handle chunks\n}",
856
+ 400 /* BadRequest */
186
857
  );
187
858
  }
188
859
  const requestBody = {
@@ -202,7 +873,7 @@ var Exa = class {
202
873
  *
203
874
  * Example usage:
204
875
  * ```ts
205
- * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
876
+ * for await (const chunk of exa.streamAnswer("What is quantum computing?", {
206
877
  * text: false,
207
878
  * systemPrompt: "Answer in a concise manner suitable for beginners."
208
879
  * })) {
@@ -228,27 +899,27 @@ var Exa = class {
228
899
  });
229
900
  if (!response.ok) {
230
901
  const message = await response.text();
231
- throw new Error(
232
- `Request failed with status ${response.status}. ${message}`
233
- );
902
+ throw new ExaError(message, response.status, (/* @__PURE__ */ new Date()).toISOString());
234
903
  }
235
904
  const reader = response.body?.getReader();
236
905
  if (!reader) {
237
- throw new Error("No response body available for streaming.");
906
+ throw new ExaError(
907
+ "No response body available for streaming.",
908
+ 500,
909
+ (/* @__PURE__ */ new Date()).toISOString()
910
+ );
238
911
  }
239
912
  const decoder = new TextDecoder();
240
913
  let buffer = "";
241
914
  try {
242
915
  while (true) {
243
916
  const { done, value } = await reader.read();
244
- if (done)
245
- break;
917
+ if (done) break;
246
918
  buffer += decoder.decode(value, { stream: true });
247
919
  const lines = buffer.split("\n");
248
920
  buffer = lines.pop() || "";
249
921
  for (const line of lines) {
250
- if (!line.startsWith("data: "))
251
- continue;
922
+ if (!line.startsWith("data: ")) continue;
252
923
  const jsonStr = line.replace(/^data:\s*/, "").trim();
253
924
  if (!jsonStr || jsonStr === "[DONE]") {
254
925
  continue;
@@ -300,9 +971,71 @@ var Exa = class {
300
971
  }
301
972
  return { content, citations };
302
973
  }
974
+ /**
975
+ * Creates and runs a research task in a blocking manner.
976
+ *
977
+ * Both parameters are required and have fixed shapes:
978
+ * 1. `input`
979
+ * `{ instructions: string }`
980
+ * • `instructions` – High-level guidance that tells the research agent what to do.
981
+ * 2. `output`
982
+ * defines the exact structure you expect back, and guides the research conducted by the agent.
983
+ * `{ schema: JSONSchema }`.
984
+ * The agent’s response will be validated against this schema.
985
+ *
986
+ * @param {{ instructions: string }} input The research prompt.
987
+ * @param {{ schema: JSONSchema }} output The desired output schema.
988
+ * @returns {Promise<ResearchTaskResponse>} The research response.
989
+ *
990
+ * @example
991
+ * const response = await exa.researchTask(
992
+ * { instructions: "I need a few key facts about honey pot ants." },
993
+ * {
994
+ * schema: {
995
+ * type: "object",
996
+ * required: ["scientificName", "primaryRegions"],
997
+ * properties: {
998
+ * scientificName: { type: "string" },
999
+ * primaryRegions: { type: "string" },
1000
+ * },
1001
+ * },
1002
+ * },
1003
+ * );
1004
+ */
1005
+ async researchTask(input, output) {
1006
+ const body = {
1007
+ input,
1008
+ output
1009
+ };
1010
+ return await this.request(
1011
+ "/research/tasks",
1012
+ "POST",
1013
+ body
1014
+ );
1015
+ }
303
1016
  };
304
- var src_default = Exa;
1017
+ var index_default = Exa2;
305
1018
  export {
306
- src_default as default
1019
+ CreateEnrichmentParametersFormat,
1020
+ CreateWebsetSearchParametersBehaviour,
1021
+ EventType,
1022
+ Exa2 as Exa,
1023
+ ExaError,
1024
+ HttpStatusCode,
1025
+ ResearchStatus,
1026
+ WebhookStatus,
1027
+ WebsetEnrichmentFormat,
1028
+ WebsetEnrichmentStatus,
1029
+ WebsetEnrichmentsClient,
1030
+ WebsetItemEvaluationSatisfied,
1031
+ WebsetItemSource,
1032
+ WebsetItemsClient,
1033
+ WebsetSearchCanceledReason,
1034
+ WebsetSearchStatus,
1035
+ WebsetSearchesClient,
1036
+ WebsetStatus,
1037
+ WebsetWebhooksClient,
1038
+ WebsetsClient,
1039
+ index_default as default
307
1040
  };
308
1041
  //# sourceMappingURL=index.mjs.map