exa-js 1.8.26 → 1.9.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.js CHANGED
@@ -52,7 +52,6 @@ __export(index_exports, {
52
52
  MonitorRunType: () => MonitorRunType,
53
53
  MonitorStatus: () => MonitorStatus,
54
54
  PreviewWebsetResponseEnrichmentsFormat: () => PreviewWebsetResponseEnrichmentsFormat,
55
- ResearchClient: () => ResearchClient,
56
55
  ScopeSourceType: () => ScopeSourceType,
57
56
  UpdateMonitorStatus: () => UpdateMonitorStatus,
58
57
  WebhookStatus: () => WebhookStatus,
@@ -122,8 +121,14 @@ var WebsetsBaseClient = class {
122
121
  * @returns The response JSON
123
122
  * @throws ExaError with API error details if the request fails
124
123
  */
125
- async request(endpoint, method = "POST", data, params) {
126
- return this.client.request(`/websets${endpoint}`, method, data, params);
124
+ async request(endpoint, method = "POST", data, params, headers) {
125
+ return this.client.request(
126
+ `/websets${endpoint}`,
127
+ method,
128
+ data,
129
+ params,
130
+ headers
131
+ );
127
132
  }
128
133
  /**
129
134
  * Helper to build pagination parameters
@@ -732,11 +737,13 @@ var WebsetSearchesClient = class extends WebsetsBaseClient {
732
737
  * @param params The search parameters
733
738
  * @returns The created Webset Search
734
739
  */
735
- async create(websetId, params) {
740
+ async create(websetId, params, options) {
736
741
  return this.request(
737
742
  `/v0/websets/${websetId}/searches`,
738
743
  "POST",
739
- params
744
+ params,
745
+ void 0,
746
+ options?.headers
740
747
  );
741
748
  }
742
749
  /**
@@ -923,8 +930,14 @@ var WebsetsClient = class extends WebsetsBaseClient {
923
930
  * @param params The Webset creation parameters
924
931
  * @returns The created Webset
925
932
  */
926
- async create(params) {
927
- return this.request("/v0/websets", "POST", params);
933
+ async create(params, options) {
934
+ return this.request(
935
+ "/v0/websets",
936
+ "POST",
937
+ params,
938
+ void 0,
939
+ options?.headers
940
+ );
928
941
  }
929
942
  /**
930
943
  * Preview a webset
@@ -932,7 +945,11 @@ var WebsetsClient = class extends WebsetsBaseClient {
932
945
  * @returns The preview response showing how the query will be decomposed
933
946
  */
934
947
  async preview(params) {
935
- return this.request("/v0/websets/preview", "POST", params);
948
+ return this.request(
949
+ "/v0/websets/preview",
950
+ "POST",
951
+ params
952
+ );
936
953
  }
937
954
  /**
938
955
  * Get a Webset by ID
@@ -1075,50 +1092,25 @@ function zodToJsonSchema(schema) {
1075
1092
 
1076
1093
  // src/research/base.ts
1077
1094
  var ResearchBaseClient = class {
1078
- /**
1079
- * Initialize a new Research base client
1080
- * @param client The Exa client instance
1081
- */
1082
1095
  constructor(client) {
1083
1096
  this.client = client;
1084
1097
  }
1085
- /**
1086
- * Make a request to the Research API (prefixes all paths with `/research`).
1087
- * @param endpoint The endpoint path, beginning with a slash (e.g. "/tasks").
1088
- * @param method The HTTP method. Defaults to "POST".
1089
- * @param data Optional request body
1090
- * @param params Optional query parameters
1091
- * @returns The parsed JSON response
1092
- */
1093
1098
  async request(endpoint, method = "POST", data, params) {
1094
1099
  return this.client.request(
1095
- `/research/v0${endpoint}`,
1100
+ `/research/v1${endpoint}`,
1096
1101
  method,
1097
1102
  data,
1098
1103
  params
1099
1104
  );
1100
1105
  }
1101
- /**
1102
- * Make a request to the Research API (prefixes all paths with `/research`).
1103
- * @param endpoint The endpoint path, beginning with a slash (e.g. "/tasks").
1104
- * @param method The HTTP method. Defaults to "POST".
1105
- * @param data Optional request body
1106
- * @param params Optional query parameters
1107
- * @returns The parsed JSON response
1108
- */
1109
1106
  async rawRequest(endpoint, method = "POST", data, params) {
1110
1107
  return this.client.rawRequest(
1111
- `/research/v0${endpoint}`,
1108
+ `/research/v1${endpoint}`,
1112
1109
  method,
1113
1110
  data,
1114
1111
  params
1115
1112
  );
1116
1113
  }
1117
- /**
1118
- * Helper to build pagination parameters.
1119
- * @param pagination The pagination parameters
1120
- * @returns QueryParams object with pagination parameters
1121
- */
1122
1114
  buildPaginationParams(pagination) {
1123
1115
  const params = {};
1124
1116
  if (!pagination) return params;
@@ -1133,26 +1125,34 @@ var ResearchClient = class extends ResearchBaseClient {
1133
1125
  constructor(client) {
1134
1126
  super(client);
1135
1127
  }
1136
- async createTask(params) {
1137
- const { instructions, model, output } = params;
1138
- let schema = output?.schema;
1128
+ async create(params) {
1129
+ const { instructions, model, outputSchema } = params;
1130
+ let schema = outputSchema;
1139
1131
  if (schema && isZodSchema(schema)) {
1140
1132
  schema = zodToJsonSchema(schema);
1141
1133
  }
1142
1134
  const payload = {
1143
1135
  instructions,
1144
- model: model ?? "exa-research",
1145
- output: output ? {
1146
- schema,
1147
- inferSchema: output.inferSchema ?? true
1148
- } : { inferSchema: true }
1136
+ model: model ?? "exa-research"
1149
1137
  };
1150
- return this.request("/tasks", "POST", payload);
1138
+ if (schema) {
1139
+ payload.outputSchema = schema;
1140
+ }
1141
+ return this.request("", "POST", payload);
1151
1142
  }
1152
- getTask(id, options) {
1143
+ get(researchId, options) {
1153
1144
  if (options?.stream) {
1154
1145
  const promise = async () => {
1155
- const resp = await this.rawRequest(`/tasks/${id}?stream=true`, "GET");
1146
+ const params = { stream: "true" };
1147
+ if (options.events !== void 0) {
1148
+ params.events = options.events.toString();
1149
+ }
1150
+ const resp = await this.rawRequest(
1151
+ `/${researchId}`,
1152
+ "GET",
1153
+ void 0,
1154
+ params
1155
+ );
1156
1156
  if (!resp.body) {
1157
1157
  throw new Error("No response body for SSE stream");
1158
1158
  }
@@ -1196,59 +1196,53 @@ var ResearchClient = class extends ResearchBaseClient {
1196
1196
  };
1197
1197
  return promise();
1198
1198
  } else {
1199
- return this.request(`/tasks/${id}`, "GET");
1199
+ const params = { stream: "false" };
1200
+ if (options?.events !== void 0) {
1201
+ params.events = options.events.toString();
1202
+ }
1203
+ return this.request(
1204
+ `/${researchId}`,
1205
+ "GET",
1206
+ void 0,
1207
+ params
1208
+ );
1200
1209
  }
1201
1210
  }
1202
- /**
1203
- * @deprecated This method is deprecated and may be removed in a future release.
1204
- * @see getTask(id, {stream: true})
1205
- * Poll a research task until completion or failure.
1206
- * Polls every 1 second with a maximum timeout of 10 minutes.
1207
- * Resilient to up to 10 consecutive polling failures.
1208
- */
1209
- async pollTask(id) {
1210
- const pollingInterval = 1e3;
1211
- const maxPollingTime = 10 * 60 * 1e3;
1212
- const maxConsecutiveFailures = 10;
1211
+ async list(options) {
1212
+ const params = this.buildPaginationParams(options);
1213
+ return this.request("", "GET", void 0, params);
1214
+ }
1215
+ async pollUntilFinished(researchId, options) {
1216
+ const pollInterval = options?.pollInterval ?? 1e3;
1217
+ const timeoutMs = options?.timeoutMs ?? 10 * 60 * 1e3;
1218
+ const maxConsecutiveFailures = 5;
1213
1219
  const startTime = Date.now();
1214
1220
  let consecutiveFailures = 0;
1215
1221
  while (true) {
1216
1222
  try {
1217
- const task = await this.request(`/tasks/${id}`, "GET");
1223
+ const research = await this.get(researchId, {
1224
+ events: options?.events
1225
+ });
1218
1226
  consecutiveFailures = 0;
1219
- if (task.status === "completed" || task.status === "failed") {
1220
- return task;
1227
+ if (research.status === "completed" || research.status === "failed" || research.status === "canceled") {
1228
+ return research;
1221
1229
  }
1222
1230
  } catch (err) {
1223
1231
  consecutiveFailures += 1;
1224
1232
  if (consecutiveFailures >= maxConsecutiveFailures) {
1225
1233
  throw new Error(
1226
- `Polling failed ${maxConsecutiveFailures} times in a row for task ${id}: ${err}`
1234
+ `Polling failed ${maxConsecutiveFailures} times in a row for research ${researchId}: ${err}`
1227
1235
  );
1228
1236
  }
1229
1237
  }
1230
- if (Date.now() - startTime > maxPollingTime) {
1238
+ if (Date.now() - startTime > timeoutMs) {
1231
1239
  throw new Error(
1232
- `Polling timeout: Task ${id} did not complete within 10 minutes`
1240
+ `Polling timeout: Research ${researchId} did not complete within ${timeoutMs}ms`
1233
1241
  );
1234
1242
  }
1235
- await new Promise((resolve) => setTimeout(resolve, pollingInterval));
1243
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
1236
1244
  }
1237
1245
  }
1238
- /**
1239
- * List research tasks
1240
- * @param options Pagination options
1241
- * @returns The paginated list of research tasks
1242
- */
1243
- async listTasks(options) {
1244
- const params = this.buildPaginationParams(options);
1245
- return this.request(
1246
- "/tasks",
1247
- "GET",
1248
- void 0,
1249
- params
1250
- );
1251
- }
1252
1246
  };
1253
1247
 
1254
1248
  // src/index.ts
@@ -1333,7 +1327,7 @@ var Exa2 = class {
1333
1327
  * @returns {Promise<any>} The response from the API.
1334
1328
  * @throws {ExaError} When any API request fails with structured error information
1335
1329
  */
1336
- async request(endpoint, method, body, params) {
1330
+ async request(endpoint, method, body, params, headers) {
1337
1331
  let url = this.baseURL + endpoint;
1338
1332
  if (params && Object.keys(params).length > 0) {
1339
1333
  const searchParams = new URLSearchParams();
@@ -1348,9 +1342,20 @@ var Exa2 = class {
1348
1342
  }
1349
1343
  url += `?${searchParams.toString()}`;
1350
1344
  }
1345
+ let combinedHeaders = {};
1346
+ if (this.headers instanceof HeadersImpl) {
1347
+ this.headers.forEach((value, key) => {
1348
+ combinedHeaders[key] = value;
1349
+ });
1350
+ } else {
1351
+ combinedHeaders = { ...this.headers };
1352
+ }
1353
+ if (headers) {
1354
+ combinedHeaders = { ...combinedHeaders, ...headers };
1355
+ }
1351
1356
  const response = await fetchImpl(url, {
1352
1357
  method,
1353
- headers: this.headers,
1358
+ headers: combinedHeaders,
1354
1359
  body: body ? JSON.stringify(body) : void 0
1355
1360
  });
1356
1361
  if (!response.ok) {
@@ -1688,7 +1693,6 @@ var index_default = Exa2;
1688
1693
  MonitorRunType,
1689
1694
  MonitorStatus,
1690
1695
  PreviewWebsetResponseEnrichmentsFormat,
1691
- ResearchClient,
1692
1696
  ScopeSourceType,
1693
1697
  UpdateMonitorStatus,
1694
1698
  WebhookStatus,